EventListenerを全部消すbookmarklet

javascript:(function(){var a=document.body,b=a.parentNode;b.removeChild(a),b.appendChild(a.cloneNode(!0))})();

EventListener削除 <- bookmarklet

今まで右クリック禁止の解除、ペースト禁止の解除なんかを必要に迫られてやったりしたけど、実はこれらの解除方法は完璧じゃないです。

右クリック禁止の解除は、HTML属性のイベントを消してるだけなので、EventListenerを使っての禁止だと解除出来ないし、ペースト禁止の解除も、一応jQueryによるペースト禁止だけは解除してるけど、あとはHTML属性のイベントの削除です。
この2つのbookmarkletは、EventListenerを使っての禁止は解除出来ません。

なので、今回はEventListenerを全部消すbookmarkletを作りました。

なお、無差別に全部消すので、必要なEventListenerがあっても消してしまいます。
何かの禁止くらいにしかJavaScriptを使ってない様なサイトには使えると思うけど、JavaScriptを駆使したサイトに使うと、支障があるかも。
Googleマップとかで使ったら、たぶん何も操作出来なくなりそう。

詳細

javascript:(function(){
  var body = document.body;
  var parent = body.parentNode;
  parent.removeChild(body);
  parent.appendChild(body.cloneNode(true));
})()

EventListenerって削除しにくくて、例えばdocument.getElementsByTagName('body')[0].removeEventListener('click')みたく、イベントタイプを指定して全部削除みたいなことが出来ません。
削除するにはEventListenerとして登録した関数も指定しないと削除できません。
なので、無名関数をEventListenerとして登録してる場合、指定しようにも無名関数なので指定できず、削除もできないです。

【JavaScript】addEventListenerの無名関数をremoveEventListenerで消す方法 | Web活

サイト運営側であれば、設定したEventListenerを保持する様にしたり、無名関数でも削除出来る仕組みを作ったりは出来るけど、外から差し込むbookmarkletだとお手上げです。

また、要素に設定されてるEventListenerのリストを取得する手段も、提供されて無いっぽいです。
そんなのあっても良さそうな気がするけど、なぜかありません。

ノードを複製すると、そのノードのすべての属性とその値がコピーされます。つまり、HTML属性のイベントを含みます。addEventListener() を使用したものや、要素のプロパティに代入されたもの (例: node.onclick = fn;) は複製されません。
Node.cloneNode – Web API インターフェイス | MDN

というわけで、このbookmarkletでは、body要素をディープコピーして入れ替えるという強引な方法により、EventListenerを全部削除しています。
引用に書いてある通りcloneNodeはEventListenerは複製出来ないらしいので、body要素や子孫の要素のどこにEventListenerが設定されていても、DOMは同じだけどEventListenerが無いものに入れ替わります。
結果的に、EventListenerの全削除が出来ました。

書いた日

2016年1月15日頃
2016年9月20日頃: bookmarlket用のコードにダブルクォートが含まれてて、ドラッグしてbookmarlketを追加すると壊れる問題があり、コードを修正。

EventListenerを全部消すbookmarklet」への3件のフィードバック

  1. shokota

    こんにちは。
    Firefoxでも動き、さらにちょっとだけ短くしてみました。
    javascript:(function(d){var h=d.documentElement;h.appendChild(h.removeChild(d.body).cloneNode(!0))})(document);

  2. kanonji 投稿作成者

    コメントどもです。
    Firefoxで動かなかったですか。確かにFirefoxは常用してなくて動作確認もしなかったので、すいません。
    コードありがとうございます。ただ、修正のしやすさから、詳細にあるほうを元にしてブックマークレットはminifyで生成したいので、あとで自分でも確認してみます。

  3. kanonji 投稿作成者

    Firefox以前に、ダブルクォートが含まれててbookmarklet登録のリンクが壊れちゃってました。
    あと、Firefoxだと!function(){}()の形のbookmarkletだと、全要素が消えてtrueだけの画面になってしまうんですね。
    minifyで生成すると(function(){})()で書いていても!function(){}()に変換されてしまうので、悩ましいです。
    なんにせよ、壊れてるところが直せました。ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>