サイト上で右クリックなどを禁止設定にする方法と禁止設定を一括解除する方法。
ユーザーの利便性を損なう以外に意味が無いと思う右クリック禁止を撲滅したいので、サイト上で右クリックや要素の範囲選択を禁止にする方法と、禁止にされている場合に一括で解除する方法のメモ。
右クリックや範囲選択を禁止にする方法
サイト上で右クリックや範囲選択を禁止にするには、JavaScriptとCSSでそれぞれ下記を設定する。
- JavaScript : 「右クリック」、「コピー」、「範囲選択」のイベントの挙動を制御。
- CSS : 要素の「範囲選択」や「ドラッグ」を不可に設定。
※ この対処による禁止状態から禁止を解除しなくても、ブラウザのデベロッパーツールでソースを表示閲覧したり、ページをダウンロード保存したりできるので、コピー対策としての意味は無い。
(1) JavaScriptで制御して禁止にする方法
JavaScriptで、以下のイベント発火時にデフォルトの動作をしないように制御することで禁止にする。
- 「contextmenu」イベント
「コンテキストメニューの呼び出し」(右クリックやキーボードのショートカットなど)で発火するイベント。 - 「copy」イベント
ユーザーが「テキストをコピー」しようとしたときに発火するイベント。 - 「selectstart」イベント
ユーザーが新しい「選択範囲を指定」したときに発火するイベント。(iOS版Safariは非対応なのでCSSで対処。) - 「mousedown」イベント
ユーザーが「ポインティングデバイスのボタン」(左クリックなど)を押したときに発火するイベント。
※ 「click」イベントは「mousedown」イベントと違い、ボタンを押したあと離されたときに発火する。
※ グローバルイベントハンドラーが持つプロパティー「oncontextmenu」、「onmousedown」、 HTMLElementが持つプロパティー「oncopy」、「onselectstart」からでも上記のイベントを制御できる。
GlobalEventHandlersミックスインは、HTMLElementやDocument、Windowといったインターフェイスに共通のイベントハンドラー。(MDN Web Docs)
1. 「contextmenu」イベントのデフォルト動作を抑止
マウスの右クリックやキーボードのショートカットなどで「コンテキストメニューの表示」がされないように制御する方法。
- window(または任意のHTML要素)に「contextmenu」イベント発火時の挙動をリスナー登録。
- eventオブジェクトが持つ「preventDefault()メソッド」でデフォルトの動作をキャンセル。(ここでは「コンテキストメニューの呼び出し」がキャンセルされる。)
※ 特定のHTMLの要素の上でだけで制御したい場合は、getElementsByTagName()メソッドなどで任意の要素を取得し、その要素でイベントリスナーを設定する。
※ グローバルイベントハンドラーの「oncontextmenu」プロパティーで制御する場合は、「false」を返して実行をキャンセルする。
※ 「addEventListener」(「contextmenu」)での設定と「グローバルイベントハンドラーのプロパティー」(「oncontextmenu」)での設定の違いは、複数記述したときに「複数の内容を登録できる」か「最後の記述ですべて上書きされる」か。
※ ブラウザ上で実行されるJavaScriptではwindowオブジェクトはグローバルオブジェクトなので、「window.」は省略できる。
//「contextmenu」イベントのイベントリスナーで制御する場合
window.addEventListener('contextmenu', function(e){
e.preventDefault();
});
//グローバルイベントハンドラーの「oncontextmenu」プロパティーで制御する場合
window.oncontextmenu = function(){
return false;
};
対象要素.addEventListener(‘イベントのタイプ’, ‘関数’, ‘イベント伝播順’) : 対象要素に指定のイベントでコールする関数を指定して登録。第3引数(初期値 : false)でイベントの伝播する方向を指定できる。falseでDOM階層の下位から上位に伝播。
event.preventDefault() : eventオブジェクトのメソッド。発生したイベントの規定の動作を行わない。イベントの伝播は止めない。
2. 「copy」イベントのデフォルト動作を抑止
「テキストのコピー」ができないように制御する方法。(「クリップボードへのコピー」が処理されなくなる。)
※ windowオブジェクトは「oncopy」プロパティーを持たないので、「oncopy」プロパティーを使う場合は任意のHTML要素上で制御する。(下記では「document」上で制御。)
※ 「テキストの切り取り」にも対応する場合は、「cut」イベントか「oncut」プロパティーで制御する。
//「copy」イベントのイベントリスナーで制御する場合
window.addEventListener('copy', function(e){
e.preventDefault();
});
//HTMLElementの「oncopy」プロパティーで制御する場合
document.oncopy = function(){
return false;
};
3. 「selectstart」イベントのデフォルト動作を抑止
「範囲選択の開始」ができないように制御する方法。(テキストや画像の範囲選択ができなくなる。)
※ iOS版Safariは非対応のイベントなのでCSSで対処する。
//「selectstart」イベントのイベントリスナーで制御する場合
window.addEventListener('selectstart', function(e){
e.preventDefault();
});
//HTMLElementの「onselectstart」プロパティーで制御する場合
document.onselectstart = function(){
return false;
};
4. 「mousedown」イベントのデフォルト動作を抑止
左クリックを禁止にして「要素を選択」できないように制御する方法。(テキストや画像の範囲選択ができなくなる。)
下記ではサイト上での左クリックを完全に禁止にしているので、必要があれば要素を絞ってリスナー登録する。
※ 「click」イベントは禁止にしていないので、「click」イベントで発火するリンククリックなどはできる。
//「mousedown」イベントのイベントリスナーで制御する場合
window.addEventListener('mousedown', function(e){
e.preventDefault();
});
//グローバルイベントハンドラーの「onmousedown」プロパティーで制御する場合
document.onmousedown = function(){
return false;
};
(2) CSSで制御して禁止にする方法
サイト上の内容の「範囲選択」や「ドラッグ」を不可にするため、下記のプロパティーの値を「none」に指定する。
- user-select : サイト上の内容を範囲選択できるかを制御するプロパティー。(Can I use)
- user-drag : サイト上の内容をドラッグできるかを制御するプロパティー。(Can I use)
- pointer-events : ポインターイベントの対象を設定するプロパティー。
※ 「user-drag」は、非標準のCSSプロパティーなのでほとんどのブラウザでサポート外。
※ 「pointer-events」は、「none」の指定でクリック、ドラッグ、ホバーなどを無効にできるが、ターゲットとなる要素やブラウザによって挙動が異なる。
* {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
* {
-webkit-user-drag: none;
user-drag: none;
}
* {
pointer-events: none;
}
右クリックの禁止を解除する方法
上述の対処により、右クリックや範囲選択が禁止になる挙動を回避する方法。
- 方法1 : ブラウザの初期設定でJavaScript自体をオフにして、すべてのJavaScriptを実行できないようにする。(禁止にするためのJavaScriptが実行されないので回避できる。)
- 方法2 : ブラウザのコンソールを開いて「禁止にしないJavaScript」を実行し、元々の「禁止にしているJavaScript」をすべて上書きする。
※ DOMの構築や表示エフェクトにJavaScriptを使っているサイトでは、方法1だとサイト閲覧自体ができなくなる可能性があるので方法2の方が無難。
(1) すべてをまとめて一括解除するJavaScript
後述の解除スクリプトを、コピペ用にまとめて1行で記述したJavaScriptとブックマークレット。
1. ブックマークレット用
ブラウザのブックマークバーに追加しておけば、クリックするだけでアクティブ状態のタブで実行される。
2. コピペ用
ブラウザのデベロッパーツールでコンソールを開き、ペーストして「enter」キーで実行できる。
addEventListener('contextmenu',function(e){e.stopPropagation();},{capture:true,passive:true});addEventListener('copy',function(e){e.stopPropagation();},{capture:true,passive:true});addEventListener('cut',function(e){e.stopPropagation();},{capture:true,passive:true});addEventListener('selectstart',function(e){e.stopPropagation();},{capture:true,passive:true});addEventListener('mousedown',function(e){e.stopPropagation();},{capture:true,passive:true });const ag2style=document.createElement('style');ag2style.innerHTML='* {-webkit-user-select:auto !important;-moz-user-select:auto !important;-ms-user-select:auto !important;user-select:auto !important;-webkit-user-drag:auto !important;user-drag:auto !important;pointer-events: auto !important;}';document.body.appendChild(ag2style);
※ 右クリック禁止にする処理の発火タイミングは、「setInterval」イベント(一定時間間隔)などで細工がされていることもありえるので、必要があれば都度対処する。
(2) JavaScriptでのイベント制御を無効にする方法
JavaScriptによる禁止設定を解除するには、ブラウザ上のJavaScriptでDOMツリーよりも上となる最上位のwindowオブジェクトで「addEventListener()メソッド」を利用する。
- 「addEventListener()メソッド」の第1引数に、禁止制御を無効にしたいイベントを指定。
- 「addEventListener()メソッド」の第2引数に、eventオブジェクトが持つ「stopPropagation()メソッド」の実行をリスナー関数として登録。(「stopPropagation()メソッド」は、次のDOM階層へのイベントの伝播を抑止する。)
- 「addEventListener()メソッド」の第3引数の拡張オプションに「capture : true」を指定。(イベントの伝播方向をDOMの上位から下位に指定する。)
- 「addEventListener()メソッド」の第3引数の拡張オプションに「passive : true」を指定。(「event.preventDefault()」の呼び出しを無効にする。)
上記の設定により、禁止設定のための「event.preventDefault()」が無効化され、すべて解除される。
- windowで各イベントリスナーに「event.preventDefault()」が登録されていたとしても「passive : true」で制御され無効になる。
- 「capture : true」と「stopPropagation()メソッド」で、windowよりも下位方向のDOMツリーへのイベント伝播が止まるので、DOM内のどの要素に「event.preventDefault()」が登録されていたとしても、その要素でイベントが発火することは無く、「event.preventDefault()」が実行されることがなくなる。
「addEventListener()メソッド」の第3引数には拡張オプションがあり、オブジェクト形式で以下の指定ができる。
- capture : boolean値。DOMツリーで下位方向の他のEventTargetに伝播する前に処理されるかどうか。(「true」で、イベントがDOMの上位から処理されて下位に伝播。)
- once : boolean値。リスナーの呼び出しを1度だけにするかどうか。(「true」で、呼び出されたときに自動的に削除される。)
- passive : boolean値。登録されているリスナー(関数)をpassive listenerとするかどうか。(「true」でpassiveとした場合、リスナーは「preventDefault()」を呼び出せず、イベントのデフォルト処理を抑止できない。「preventDefault()」を呼び出しても実行されずにコンソールに警告が出力される。)
※ オブジェクト形式ではなく「false」か「true」のみを指定、または省略(初期値false)した場合は、拡張オプションではなくcaptureとして処理される。
※ 拡張オプションはすべてIE非サポート。
※ 現時点でSafariが非サポートの「signal」オプションもある。(abort()メソッドがコールされたときにリスナーを削除する。)
※ EventTarget.addEventListener()のMozillaの公式ドキュメント。
1. 「contextmenu」イベント制御の無効化
「コンテキストメニューの表示」が制御されている場合に無効化するJavaScript。
window.addEventListener('contextmenu', function(e){
e.stopPropagation();
},{
capture: true,
passive: true
});
2. 「copy」イベント制御の無効化
「テキストのコピー」をできないように制御されている場合に無効化するJavaScript。
window.addEventListener('copy', function(e){
e.stopPropagation();
},{
capture: true,
passive: true
});
//「切り取り」に対する制御も無効化
window.addEventListener('cut', function(e){
e.stopPropagation();
},{
capture: true,
passive: true
});
3. 「selectstart」イベント制御の無効化
「範囲選択の開始」をできないように制御されている場合に無効化するJavaScript。
window.addEventListener('selectstart', function(e){
e.stopPropagation();
},{
capture: true,
passive: true
});
4. 「mousedown」イベント制御の無効化
「左クリック」できないように制御されている場合に無効化するJavaScript。
window.addEventListener('mousedown', function(e){
e.stopPropagation();
},{
capture: true,
passive: true
});
(3) CSSでの制御を無効にする方法
JavaScriptでDOMに新しいstyleの記述を動的に生成してCSSを上書きする。
- style要素を動的に生成。
- 必要なCSSプロパティーを中身に記述。
- body要素の最末尾に挿入する。(より後方のstyle記述が優先されるので。)
ワイルドカード(「*」)ですべての要素のCSSプロパティー「user-select」、「user-drag」、「pointer-events」の値を「auto !important」に設定して強制的に変更。
const ag2style = document.createElement('style');
ag2style.innerHTML = '* {-webkit-user-select: auto !important;-moz-user-select: auto !important;-ms-user-select: auto !important;user-select: auto !important;-webkit-user-drag: auto !important;user-drag: auto !important;pointer-events: auto !important;}';
document.body.appendChild(ag2style);
document.createElement(‘HTML要素タグ’) : 指定したHTML要素タグを生成する。指定した要素タグが認識できない場合は、不正なHTML要素である事を表すHTMLUnknownElementを生成する。
要素.innerHTML : 指定した要素内のHTMLまたはXMLのマークアップを取得したり設定したりする。
親ノード.appendChild(‘ノード’) : 指定した親ノードの子ノードリストの末尾に指定したノードを追加する。
- 右クリックを禁止する方法と禁止を解除(回避)する方法
- イベントで「右クリック禁止」を禁止してみよう
- 右クリックを禁止・禁止解除する
- 選択禁止・右クリック禁止・キーボード操作禁止を全部解除するブックマークレット
- addEventListener の第3引数が拡張されてるという話
- JavaScriptでの要素のスタイル操作で !important を使う方法
https://memo.ag2works.tokyo/post-2557/
サイト上で右クリックなどを禁止設定にする方法と禁止設定を一括解除する方法。 | memo メモ [AG2WORKS]
<a href="https://memo.ag2works.tokyo/post-2557/" target="_blank" rel="noopener">サイト上で右クリックなどを禁止設定にする方法と禁止設定を一括解除する方法。 | memo メモ [AG2WORKS]</a>
この記事へのコメント
コメントの書き込みはまだありません。