読者です 読者をやめる 読者になる 読者になる

nikkansports.comで右クリックを有効にしたい。その2

GreaseMonkey

昨日挫折しかかったnikkansports.comの右クリックを有効にするぐりもんの記事にid:poolmmjpから

getElementsByTagNameにして、返るのはリストだからループするなり[0]だけ処理するなり。さらにoncontextmenu=handlerじゃなく、setAttribute ('oncontextmenu', handler)。あとonload存在チェック。

とブクマコメントをいただいたので早速試してみました。ぷーるさんどうもありがとうございます!

(function(){
	var w = (typeof unsafeWindow == 'undefined') ? window : unsafeWindow;
	function handler(){ return true }
	function unprotect(){
		with(w){
			var body = document.getElementsByTagName('body');
			if(body[0]){
				body[0].setAttribute('oncontextmenu', handler);
			}
		}
	}

	var onload = w.onload;
	if(onload){
		w.onload = function(){
			onload();
			unprotect();
		}
	}
})();

まず、getElementByTagNameはtypoじゃなくて、両方あんのかな?くらいに思ってました。切ない気分になるね ><

最後のところなんですが、onloadをチェックっていうのはこういうことかな?としたんだけど、これじゃうまく動かない。どうもonloadがnullのようでifの中に入らないみたい。ifをとってFireBugでみるとこのonloadがないよーってエラーが出てる。

そこで下のように書いたら動いてる。エラーもでないみたい。

(function(){
	var w = (typeof unsafeWindow == 'undefined') ? window : unsafeWindow;
	function handler(){ return true }
	function unprotect(){
		with(w){
			var body = document.getElementsByTagName('body');
			if(body[0]){
				body[0].setAttribute('oncontextmenu', handler);
			}
		}
	}

	var onload = w.onload;
	if(onload){
		w.onload = function(){
			onload();
			unprotect();
		}
	}else{
		unprotect();
	}
})();

ちょっと調べてみたらわかりました。Greasemonkeyの開発をまとめてみるによると、

  • unsafeWindowっていうのはGreaseMonkeyが動いているページのこと。
  • unsafeWindowから元のページの関数を呼ぶことができる。
  • これでLDRのヒトをしゃべらせたりできる。

で、上のスクリプトでは「元のページのonload関数を上書き」しようとしてるからonload関数が定義されてないnikkansports.comではここがnullになる。ということらしい。

このスクリプト最速インターフェース研究会 :: アメブロのオフィシャルブログ画像保護機能を無効化するGreasemonkeyスクリプトを真似させてもらったんだけど、このスクリプトの対象はアメブロだからアメブロでは定義されてるonloadを上書きするという仕様になってるということなんだと思う。

そのままロクに理解もしないで丸パクりしてごめんなさい ><
つーことはifとかelseなんてしないで直にunprotect();で良いのかな。 動くことは動いてる。oncontextmenu使って右クリック禁止してるサイトさんで汎用的に使えるようにするためにはどうするんだろ。

スクリプトはとりあえずここにおいておきます。
permit_right_click.user.js
たぶんnikkansports.comに限らずoncontextmenuで右クリ禁止のサイトではそれなりに効果があるはず。一応nikkansports.comでしか発動しないようになってるんで適宜追加してください。