バックスペースキーが元に戻らないようにするにはどうすればよいですか?


275

IEでは、(ひどく非標準ですが機能している)jQueryでこれを行うことができます

if ($.browser.msie)
    $(document).keydown(function(e) { if (e.keyCode == 8) window.event.keyCode = 0;});

しかし、Firefoxで動作する方法で、またはボーナスのためにクロスブラウザの方法で行うことは可能ですか?

記録のために:

$(document).keydown(function(e) { if (e.keyCode == 8) e.stopPropagation(); });

何もしません。

$(document).keydown(function(e) { if (e.keyCode == 8) e.preventDefault(); });

問題は解決しますが、ページでバックスペースキーが使用できなくなります。これは、元の動作よりもさらに悪いものです。

編集:これを行う理由は、単純なWebページではなく大きなアプリケーションを作成しているためです。間違った場所でバックスペースを押したからといって、10分の作業を失うのは信じられないほど煩わしいことです。間違いを防止することとユーザーを煩わしいものにすることの比率は、バックスペースキーが戻るのを防ぐことにより、1000/1をはるかに超える必要があります。

EDIT2:私は履歴ナビゲーションを防止しようとしているのではなく、ただの事故です。

EDIT3:@brentonstrinesコメント(質問が非常に人気があるため、ここに移動しました):これは長期的な「修正」ですが、サポートを Chromiumバグの、Webkitでこの動作を変更


137
バックスペースキーがオーバーロードされているためです。気づかなかったかもしれませんが、おそらくテキストフィールドに入力したばかりの文字を消去するために、いつもそれを使用しています。一部の顧客はページに戻る原因で問題を抱えているため、これは有用な情報です。バックスペースがページに戻ることになっていることを知っているのは、ピエロだけです。それは私が知らなかったものであり、ブラウザが持っていることは完全に敵対的な行動です。すべてのページでその動作を無効にする必要があると思います。
ブルトン語

80
なぜ人々はこれが奇妙だと思うのですか?ナビゲーションにバックスペースを使用することは、本当におかしなショートカットです!ユーザーがテキストを削除したいテキストフィールドがたくさんある場合-長いSO回答があり、別のウィンドウに切り替えて何かを確認した後、戻って編集領域を誤ってクリックし、Backspaceキーを押して単語を削除します。突然、ブラウザがページに戻り、書き込んだばかりの内容がすべて失われる可能性があります。
Peter Boughton、

57
なぜこれをしたいのですか?Webサイトではなく、Webアプリケーションを作成しています。一部の入力フィールドは読み取り専用であり、その場合は編集可能に見えますが、Backspaceキーを押すとページを離れます。消去何かしようとしてナビゲートバック対バックスペースを押すしようとバックスペースを押すの割合ははるかに少ない1/1000よりもおそらくある
erikkallen

42
問題は、これを行う方法であり、それが良いアイデアであるかどうかについてのあなたの意見ではありません。プロジェクトの詳細を知らなければ、あなたの意見は無意味です。私のクライアントは、私のプロジェクトの1つにこの動作を具体的に要求し、「なぜそれを実行したいのか」ではなく実際の回答を求めています。参考になります。
なし

7
これは長期的な「修正」ですが、Chromiumバグの背後にサポートを投入して、webkitでこの動作を変更することができます:code.google.com/p/chromium/issues/detail
id=

回答:


335

このコードは、少なくともIEとFirefoxで問題を解決します(他のテストは行っていませんが、問題が他のブラウザーに存在する場合でも機能する可能性は十分あります)。

// Prevent the backspace key from navigating back.
$(document).unbind('keydown').bind('keydown', function (event) {
    if (event.keyCode === 8) {
        var doPrevent = true;
        var types = ["text", "password", "file", "search", "email", "number", "date", "color", "datetime", "datetime-local", "month", "range", "search", "tel", "time", "url", "week"];
        var d = $(event.srcElement || event.target);
        var disabled = d.prop("readonly") || d.prop("disabled");
        if (!disabled) {
            if (d[0].isContentEditable) {
                doPrevent = false;
            } else if (d.is("input")) {
                var type = d.attr("type");
                if (type) {
                    type = type.toLowerCase();
                }
                if (types.indexOf(type) > -1) {
                    doPrevent = false;
                }
            } else if (d.is("textarea")) {
                doPrevent = false;
            }
        }
        if (doPrevent) {
            event.preventDefault();
            return false;
        }
    }
});

6
パスワードフィールドを分割します。
ヘムロック

7
ヘムロックが述べたように- d.type.toUpperCase() === 'PASSWORD'同様に確認してください。それ以外はよさそうだ
stevendesu

17
すでにjQueryを使用しているためif( $(d).is( ":input" ) )...
Paul Alexander

23
これは、「戻る」機能をブラックリストに載せることができるのではなく、ホワイトリストでなければならないことを吸い込みます。d.isContentEditableここにチェックを追加することができます。
iono 2013

3
私は現在受け入れられている回答のクリーンバージョンであるNPMプロジェクトを作成しました:github.com/slorber/backspace-disabler(これはcontenteditablesもサポートし、依存関係はありません)
Sebastien Lorber

62

このコードはすべてのブラウザで機能し、フォーム要素上にない場合、またはフォーム要素が無効|読み取り専用の場合は、バックスペースキーを飲み込みます。これは効率的でもあります。これは、入力されたすべてのキーで実行されるときに重要です。

$(function(){
    /*
     * this swallows backspace keys on any non-input element.
     * stops backspace -> back
     */
    var rx = /INPUT|SELECT|TEXTAREA/i;

    $(document).bind("keydown keypress", function(e){
        if( e.which == 8 ){ // 8 == backspace
            if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                e.preventDefault();
            }
        }
    });
});

1
私の例をテストしてください、それに応じてコードを更新したいかもしれません。
Biff MaGriff

10
クリーンなため、@ erikkallenのソリューションよりもこちらの方が好きです。:しかし、私はこれまでであれば()を変更しても、無視されることにボタン、ラジオボタン、チェックボックスを提出したかったif(!rx.test(e.target.tagName) || $(e.target).is(':checkbox') || $(e.target).is(':radio') || $(e.target).is(':submit') || e.target.disabled || e.target.readOnly )
マシュー・クラーク

@thetoolman、エリカレンの回答に関する私のコメントを参照してください。これも考慮する必要がありますcontentEditable
2013年

10
@MaffooClock:より簡潔にすることができます .is(':checkbox,:radio,:submit')
cdmckay 14

1
@cdmckay:そもそもそのように書いていないなんて信じられません。私たち全員のためにそれを片付けてくれてありがとう:)
マシュー・クラーク

41

ここでの他の回答は、Backspaceが許可されている要素をホワイトリストに登録しないとこれを実行できないことを確立しています。ホワイトリストは単なるtextareasとtext / password入力ほど単純ではないため、このソリューションは理想的ではありませんが、不完全であり、更新する必要があることが繰り返し見つかります。

ただし、バックスペース機能を抑制する目的は、ユーザーが誤ってデータを失うのを防ぐことだけであるので、モーダルポップアップは驚くべきものであるため、beforeunloadのソリューションは適切です。標準のワークフローの一部としてトリガーされると、モーダルポップアップは悪い状態になります。ユーザーがそれらを読まないでそれらを却下することに慣れていて、彼らは迷惑だからです。この場合、モーダルポップアップは、まれで意外なアクションの代替としてのみ表示されるため、許容されます。

問題は、ユーザーがページから移動したとき(リンクをクリックしたときやフォームを送信したときなど)にonbeforeunloadモーダルがポップアップしてはならず、特定のonbeforeunload条件のホワイトリストまたはブラックリストの作成を開始しないことです。

一般化されたソリューションのトレードオフの理想的な組み合わせは次のとおりです。バックスペースが押されているかどうかを追跡し、押されている場合のみonbeforeunloadモーダルをポップアップします。言い換えると:

function confirmBackspaceNavigations () {
    // http://stackoverflow.com/a/22949859/2407309
    var backspaceIsPressed = false
    $(document).keydown(function(event){
        if (event.which == 8) {
            backspaceIsPressed = true
        }
    })
    $(document).keyup(function(event){
        if (event.which == 8) {
            backspaceIsPressed = false
        }
    })
    $(window).on('beforeunload', function(){
        if (backspaceIsPressed) {
            backspaceIsPressed = false
            return "Are you sure you want to leave this page?"
        }
    })
} // confirmBackspaceNavigations

これは、IE7 +、FireFox、Chrome、Safari、およびOperaで動作することがテストされています。この関数をglobal.jsにドロップし、ユーザーが誤ってデータを失いたくない任意のページから呼び出します。

onbeforeunloadモーダルは一度しかトリガーできないので、ユーザーがもう一度Backspaceを押すと、モーダルは再び起動されないことに注意してください。

これはhashchangeイベントではトリガーされないことに注意してください。ただし、そのコンテキストでは、他の手法を使用して、ユーザーが誤ってデータを失うのを防ぐことができます。


2
私はこれと同じソリューションを追加したところ、ページの下部にこの投稿が表示されました。私が持っている1つの違いは、return "Are you sure ..."ステートメントの前にlastUserInputWasBackspace = falseを設定することです。これにより、ポップアップがすでに表示された後でボタンをクリックしても、ポップアップが表示されません(したがって、バックスペースの影響を受ける動作)。
David Russell、

1
@ user2407309私は、Firefoxがソリューションで機能しないというコメント(苦情ではありません)を削除しました。デバッガに問題がありました。あなたのコードを編集/破壊したことをお詫びします。私は自分の限界を超えて(編集)、私を許してしまったことに気づきました。本当に申し訳ありません。この問題に対するあなたの素晴らしい解決策に文句を言うつもりはありません。重ねて申し訳ありません。このコードはうまく機能します。これが最良の答えだと私は信じています。
Charles Byrne

1
このソリューションは私のローカルマシンで機能しましたが、移動すると、クライアント(少なくとも一部)はアプリケーションの半分の機能を失いました。何かがそれを拒否していると思いますが、私には何がわかりません。
Steve

1
@Steve、珍しいかどうか、機能に問題がある場合、その情報はここに属します。本当に問題があるのか​​知りたいだけです。
Vladimir Kornea 2015年

1
素晴らしい解決策ですが、残念ながらユーザーが誤って2回バックスペースを押した場合でも、元に戻ります。(少なくともFirefoxで)
Remco de Zwart 2017年

26

よりエレガントで簡潔なソリューション:

$(document).on('keydown',function(e){
  var $target = $(e.target||e.srcElement);
  if(e.keyCode == 8 && !$target.is('input,[contenteditable="true"],textarea'))
  {
    e.preventDefault();
  }
})

1
これははるかに簡潔であり、私が言えることは同じように機能します。なぜ最も人気のある答えは、入力のタイプのすべてのそれらのチェックを持ち、より複雑に見えるのですか?より信頼できますか?
ニアポイント2014

1
最も人気のある回答は、質問に最初に回答した回答でした。
Darwayne

4
読み取り専用フィールドがフォーカスされている場合、削除は引き続きChromeに戻ります
Will D

16

さまざまな入力タイプに対処するためのerikkallenの回答の変更

私は、エンタープライズユーザーがチェックボックスまたはラジオボタンのバックスペースを押してそれをクリアしようとしても、それをクリアしようとすると、後方に移動してすべてのデータを失う可能性があることがわかりました。

この変更により、その問題に対処する必要があります。

コンテンツ編集可能なdivに対処するための新しい編集

    //Prevents backspace except in the case of textareas and text inputs to prevent user navigation.
    $(document).keydown(function (e) {
        var preventKeyPress;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            switch (d.tagName.toUpperCase()) {
                case 'TEXTAREA':
                    preventKeyPress = d.readOnly || d.disabled;
                    break;
                case 'INPUT':
                    preventKeyPress = d.readOnly || d.disabled ||
                        (d.attributes["type"] && $.inArray(d.attributes["type"].value.toLowerCase(), ["radio", "checkbox", "submit", "button"]) >= 0);
                    break;
                case 'DIV':
                    preventKeyPress = d.readOnly || d.disabled || !(d.attributes["contentEditable"] && d.attributes["contentEditable"].value == "true");
                    break;
                default:
                    preventKeyPress = true;
                    break;
            }
        }
        else
            preventKeyPress = false;

        if (preventKeyPress)
            e.preventDefault();
    });


テストでmake 2ファイルを作成します。

starthere.htm-最初にこれを開いて、戻る場所を用意します

<a href="./test.htm">Navigate to here to test</a>

test.htm-これは、チェックボックスまたは送信にフォーカスがあるときにバックスペースが押されると、後方に移動します(タブで実行)。修正するコードに置き換えます。

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">

    $(document).keydown(function(e) {
        var doPrevent;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            if (d.tagName.toUpperCase() == 'INPUT' || d.tagName.toUpperCase() == 'TEXTAREA') {
                doPrevent = d.readOnly || d.disabled;
            }
            else
                doPrevent = true;
        }
        else
            doPrevent = false;

        if (doPrevent)
            e.preventDefault();
    });
</script>
</head>
<body>
<input type="text" />
<input type="radio" />
<input type="checkbox" />
<input type="submit" />
</body>
</html>

radio | checkbox | submit-> back functionでバックスペースプレスを押したのはどのブラウザですか。私はブラウザを見たhavent行う。この...
thetoolman

Internet Explorer 8とChrome
Biff MaGriff

2
私はこのスレッドで他のいくつかの解決策を試しましたが、これは私のすべての状況でうまく機能し、コードを最もクリーンで理解しやすいものにしました。ありがとうございました。
エズワード2013

@Darwayneを試してみましたか?なぜこれが非常に短く、これがより複雑であるのか知りたいのですが、どちらも同じように機能しているようです
Nearpoint

これはリンクで機能しますか?アイテムを削除するための画像ボタンを備えたASP.Netアプリケーションがあります。それは...これは、これまでに取り組んでいなかっただけのことだ
スティーブ・

8

コメントに基づいて、バックスペースを押して削除してもフィールドがフォーカスされていない場合に、フォーム内の情報を失わないようにする必要があるようです。

その場合は、onunloadイベントハンドラを確認します。Stack Overflowはそれを使用します。回答を書き始めたときにページを離れようとすると、警告がポップアップ表示されます。


4
失礼なコメントでした。つまり、ユーザーはおそらく、自分が間違っていたことさえ知らなかった何かをすることで非難されたくないでしょう。onkeydownを使って静かにキーを食べてみませんか?目標は、ユーザーがページを離れることを完全に防ぐことではなく、この一般的な間違いを防ぐことです。さらに、ポップアップダイアログはあまり効果的ではなく、役に立ちません。ユーザーはそれらを読みません。ページを離れてもよろしいですか?はい!待つ必要はありません。ページを離れたくありませんでした。
ブルトン

3
OK、それを取るか、そのままにしておきます。あなたは、実際には存在しない、または少なくとも重要ではない問題を過度に設計しようとしていると思います。そして、私の経験では、見慣れないダイアログを正しく読み上げずに「OK」をクリックするのは、パワーユーザーだけです。;)
DisgruntledGoat 09/09/30

3
あなたとブルトン人は同じ人ですか?とにかく、あなたはそこに足を踏み入れました-記事は「デフォルトの答えはキャンセルです」と言っているので、ページを離れることについてのダイアログを見ると、彼らは「キャンセル」を押してページを離れません。ただし、このダイアログでのChromeのオプションは「このページを離れる」と「このページにとどまる」ですが、これらは非常に明確です。
DisgruntledGoat 09/09/30

1
いいえ、彼は私ではありませんが、以前にそのリンクに出くわしました。コメントは陽気だと思います。"!!人々はモーダルダイアログボックスを無視しますか?私たちはそれらをさらに永続的で煩わしいものにする方法を見つけなければなりません!"。マイクロソフトのソフトウェアについて本当にたくさん説明しています。
ブルトン

3
@不満:いいえ、私はブルトンではありません。この記事の目的は「デフォルトの選択は...」ではなく、「ユーザーは何も読まない」ことです。
erikkallen

7

このコードをナビゲートしないでください。

$(document).on("keydown", function (event) {        
   if (event.keyCode === 8) {
      event.preventDefault();
    }
  });

しかし、テキストフィールドを制限するのではなく、他のもののために

$(document).on("keydown", function (event) {
  if (event.which === 8 && !$(event.target).is("input, textarea")) {
   event.preventDefault();
  }
});

特定のフィールドでそれを防ぐには、単に

$('#myOtherField').on("keydown", function (event) {
  if (event.keyCode === 8 || event.which === 8) { 
   event.preventDefault(); 
  } 
});

以下を参照してください!

BACKSPACEがjQueryでナビゲートしないようにする(Googleのホームページのように)


7

答えのほとんどはjqueryにあります。これは、純粋なJavascriptで完璧に実行できます。シンプルで、ライブラリは必要ありません。この記事は私にとって良い出発点でしたが、keyIdentifierは非推奨であるため、このコードをより安全にしたかったので、|| e.keyCode == 8をifステートメントに追加しました。また、Firefoxではコードがうまく機能していなかったため、return falseを追加しました。そして今、それは完全にうまく機能します。ここにあります:

<script type="text/javascript">
window.addEventListener('keydown',function(e){if(e.keyIdentifier=='U+0008'||e.keyIdentifier=='Backspace'||e.keyCode==8){if(e.target==document.body){e.preventDefault();return false;}}},true);
</script>

このコードは素晴らしいので、

  1. それは純粋なjavascriptです(ライブラリは必要ありません)。
  2. 押されたキーをチェックするだけでなく、アクションが本当にブラウザの「戻る」アクションかどうかを確認します。
  3. 上記と一緒に、ユーザーはWebページの入力テキストボックスからテキストを入力して削除できますが、[戻る]ボタンのアクションは妨げられません。
  4. それは短く、きれいで、速く、要点はまっすぐです。

console.log(e);を追加できます。テスト目的で、ChromeでF12を押し、「コンソール」タブに移動して、ページの「バックスペース」を押し、その中を調べて返される値を確認します。次に、これらのすべてのパラメーターを対象にして、コードをさらに拡張できます上記のあなたのニーズに合わせて。


6

「thetoolman」と「Biff MaGriff」が提供するソリューションを組み合わせる

次のコードはIE 8 / Mozilla / Chromeで正しく動作するようです

$(function () {
    var rx = /INPUT|TEXTAREA/i;
    var rxT = /RADIO|CHECKBOX|SUBMIT/i;

    $(document).bind("keydown keypress", function (e) {
        var preventKeyPress;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            if (rx.test(e.target.tagName)) {
                var preventPressBasedOnType = false;
                if (d.attributes["type"]) {
                    preventPressBasedOnType = rxT.test(d.attributes["type"].value);
                }
                preventKeyPress = d.readOnly || d.disabled || preventPressBasedOnType;
            } else {preventKeyPress = true;}
        } else { preventKeyPress = false; }

        if (preventKeyPress) e.preventDefault();
    });
}); 

IMAGEを追加することも役立つ場合があります。
mrswadge 2014

私はこれに決めました。
Corentin

5

誰もなぜこれに答えなかったのかわからない-それが可能かどうかを尋ねる完全に合理的な技術的な質問のようです。

いいえ、ブラウザ間でBackspaceボタンを無効にする方法はないと思います。私はそれが最近FFでデフォルトで有効になっていないことを知っています。


3
実際の質問に答えずに時間を浪費したことに対するマイナス1
Andrew

3

このソリューションは、投稿されている他のソリューションと似ていますが、シンプルなホワイトリストを使用して、.is()関数でセレクターを設定するだけで、簡単にカスタマイズして、指定した要素のバックスペースを許可できます。

私はそれをこのフォームで使用して、ページのバックスペースがナビゲートしないようにします。

$(document).on("keydown", function (e) {
    if (e.which === 8 && !$(e.target).is("input:not([readonly]), textarea")) {
        e.preventDefault();
    }
});

2
ユーザーがcontenteditableを使用すると、これは無効になります。したがって、ホワイトリストにcontenteditable = trueを追加することもできます
Miguel

3

@erikkallenの優れた答えを少し詳しく説明するために、HTML5で導入されたものを含め、すべてのキーボードベースの入力タイプを許可する関数を次に示します

$(document).unbind('keydown').bind('keydown', function (event) {
    var doPrevent = false;
    var INPUTTYPES = [
        "text", "password", "file", "date", "datetime", "datetime-local",
        "month", "week", "time", "email", "number", "range", "search", "tel",
        "url"];
    var TEXTRE = new RegExp("^" + INPUTTYPES.join("|") + "$", "i");
    if (event.keyCode === 8) {
        var d = event.srcElement || event.target;
        if ((d.tagName.toUpperCase() === 'INPUT' && d.type.match(TEXTRE)) ||
             d.tagName.toUpperCase() === 'TEXTAREA') {
            doPrevent = d.readOnly || d.disabled;
        } else {
            doPrevent = true;
        }
    }
    if (doPrevent) {
        event.preventDefault();
    }
});

おかげで、私はこの答えを使用しています!これまでにこの解決策で何か問題を見つけましたか?
ニアポイント2014

1
すべてのkeydownイベントで再計算されないように、関数からINPUTTYPES、TEXTRE宣言を移動することをお勧めします。
thetoolman 2014年

3

JavaScript-jQueryの方法:

$(document).on("keydown", function (e) {
    if (e.which === 8 && !$(e.target).is("input, textarea")) {
        e.preventDefault();
    }
});

JavaScript-ネイティブな方法で、私にとってはうまくいきます:

<script type="text/javascript">

//on backspace down + optional callback
function onBackspace(e, callback){
    var key;
    if(typeof e.keyIdentifier !== "undefined"){
        key = e.keyIdentifier;

    }else if(typeof e.keyCode !== "undefined"){
        key = e.keyCode;
    }
    if (key === 'U+0008' || 
        key === 'Backspace' || 
        key === 8) {
                    if(typeof callback === "function"){
                callback();
            }
            return true;
        }
    return false;
}

//event listener
window.addEventListener('keydown', function (e) {

    switch(e.target.tagName.toLowerCase()){
        case "input":
        case "textarea":
        break;
        case "body":
            onBackspace(e,function(){
                e.preventDefault();
            });

        break;
    }
}, true);
</script>

@MichaelPotterずっと前の私のユースケースでは大丈夫でした。私の答えを改善/変更して、貢献してください。どうも!
Vladimir Djuricic 2017

3

JQUERY以外の回答を見つけるのに苦労しました。私を軌道に乗せてくれたStasに感謝します。

クロム: クロスブラウザーのサポートが必要ない場合は、ホワイトリストではなくブラックリストを使用できます。この純粋なJSバージョンはChromeでは機能しますが、IEでは機能しません。FFについてはわかりません。

Chrome(バージョン36、2014年半ば)では、入力要素またはコンテンツ編集可能要素ではないキープレスがを対象とするようです<BODY>。これにより、ホワイトリストよりもブラックリストの使用が可能になります。IEはラストクリックターゲットを使用しているため、divまたはその他の可能性があります。そのため、IEではこれは役に立たなくなります。

window.onkeydown = function(event) {
    if (event.keyCode == 8) {
    //alert(event.target.tagName); //if you want to see how chrome handles keypresses not on an editable element
        if (event.target.tagName == 'BODY') {
            //alert("Prevented Navigation");
            event.preventDefault();
        }
    }
}  

クロスブラウザー: 純粋なJavaScriptの場合、私はStasの回答が最良であることがわかりました。contenteditableの条件チェックをもう1つ追加すると、動作します*:

document.onkeydown = function(e) {stopDefaultBackspaceBehaviour(e);}
document.onkeypress = function(e) {stopDefaultBackspaceBehaviour(e);}

function stopDefaultBackspaceBehaviour(event) {
    var event = event || window.event;
    if (event.keyCode == 8) {
        var elements = "HTML, BODY, TABLE, TBODY, TR, TD, DIV";
        var d = event.srcElement || event.target;
        var regex = new RegExp(d.tagName.toUpperCase());
        if (d.contentEditable != 'true') { //it's not REALLY true, checking the boolean value (!== true) always passes, so we can use != 'true' rather than !== true/
            if (regex.test(elements)) {
                event.preventDefault ? event.preventDefault() : event.returnValue = false;
            }
        }
    }
}

* IE [編集:およびSpartan / TechPreview]には、テーブル関連の要素を編集不可にする「機能」があることに注意してください。それらの1つをクリックしてから、Backspaceキーを押すと、元に戻ります。編集可能ながない場合<td>、これは問題ではありません。


2

承認されたソリューションとSelect2.jsプラグインにいくつか問題がありました。削除アクションが妨げられていたため、編集可能ボックスの文字を削除できませんでした。これは私の解決策でした:

//Prevent backwards navigation when trying to delete disabled text.
$(document).unbind('keydown').bind('keydown', function (event) {

    if (event.keyCode === 8) {

        var doPrevent = false,
            d = event.srcElement || event.target,
            tagName = d.tagName.toUpperCase(),
            type = (d.type ? d.type.toUpperCase() : ""),
            isEditable = d.contentEditable,
            isReadOnly = d.readOnly,
            isDisabled = d.disabled;

        if (( tagName === 'INPUT' && (type === 'TEXT' || type === 'PASSWORD'))
            || tagName === 'PASSWORD'
            || tagName === 'TEXTAREA') {
            doPrevent =  isReadOnly || isDisabled;
        }
        else if(tagName === 'SPAN'){
            doPrevent = !isEditable;
        }
        else {
            doPrevent = true;
        }
    }

    if (doPrevent) {
        event.preventDefault();
    }
});

Select2は、「contentEditable」の属性を持つスパンを作成します。これは、その中の編集可能なコンボボックスに対してtrueに設定されています。スパンのtagNameと異なる属性を説明するコードを追加しました。これは私のすべての問題を解決しました。

編集:jqueryにSelect2 comboboxプラグインを使用していない場合、このソリューションは必要ない可能性があり、受け入れられているソリューションの方が優れている場合があります。


1
    document.onkeydown = function (e) {    
        e.stopPropagation();
        if ((e.keyCode==8  ||  e.keyCode==13) &&
            (e.target.tagName != "TEXTAREA") && 
            (e.target.tagName != "INPUT")) { 
            return false;
        }
    };

2
return falseは使用しないでください。e.preventDefaultをお勧めします。また、バックスペースだけでなく、すべてのキーのイベントの伝播を停止します。最後に、keyCode 13が入力されました。質問はバックスペースを使用したバックナビゲーションの防止に関するものでしたが、これにより、Enterによるフォームの送信や他のアクションの実行が妨げられます。
なし

1

このコードは、すべてのブラウザーの問題を解決します。

onKeydown:function(e)
{
    if (e.keyCode == 8) 
    {
      var d = e.srcElement || e.target;
      if (!((d.tagName.toUpperCase() == 'BODY') || (d.tagName.toUpperCase() == 'HTML'))) 
      {
         doPrevent = false;
      }
       else
      {
         doPrevent = true;
      }
    }
    else
    {
       doPrevent = false;
    }
      if (doPrevent)
      {
         e.preventDefault();
       }

  }

1
d.tagnameがDIVまたはであるため、このコードは期待どおりに機能しませんTD
Biff MaGriff、2011年

Haseeb AkhtarのコードはChromeとFirefoxで完璧に動作しますが、驚きです!! IE6-9にはありません。
Martin Andersen

1

バックスペースを押したときにナビゲーションを防止する最も簡単な方法

$(document).keydown(function () {
    if (event.keyCode == 8) {
        if (event.target.nodeName == 'BODY') {
            event.preventDefault();
        }
    }
});

backspcaeを押すことによるナビゲーションを防止し、同時にすべての入力コントロールでバックスペースを許可します
Mohammed Irfan Mayan

そして、最初の行をお見逃しなく.. $(document).keydown(function(){
Mohammed Irfan Mayan

3
これにより、
textarea

1

Dojoツールキット1.7を使用すると、これはIE 8で機能します。

require(["dojo/on", "dojo/keys", "dojo/domReady!"],
function(on, keys) {
    on(document.body,"keydown",function(evt){if(evt.keyCode == keys.BACKSPACE)evt.preventDefault()});
});

1

読み取り専用のテキストフィールドに次の属性を追加するという非常に簡単な解決策を試しましたか。

onkeydown = "return false;"

これにより、読み取り専用のテキストフィールドでBackspaceキーが押されたときに、ブラウザが履歴に戻ることはありません。多分私はあなたの本当の意図を見逃しているかもしれませんが、これがあなたの問題の最も簡単な解決策であるようです。


1

よりすっきりとしたソリューション-

$(document).on('keydown', function (e) {
    var key = e == null ? event.keyCode : e.keyCode;
    if(key == 8 && $(document.activeElement.is(':not(:input)')))   //select, textarea
      e.preventDefault();
});

または、次の場合にのみ確認できます。

$(document.activeElement).is('body')

1

すべてのブラウザで機能する純粋なJavaScriptバージョン:

document.onkeydown = function(e) {stopDefaultBackspaceBehaviour(e);}
document.onkeypress = function(e) {stopDefaultBackspaceBehaviour(e);}

function stopDefaultBackspaceBehaviour(event) {
  var event = event || window.event;
  if (event.keyCode == 8) {
    var elements = "HTML, BODY, TABLE, TBODY, TR, TD, DIV";
    var d = event.srcElement || event.target;
    var regex = new RegExp(d.tagName.toUpperCase());
    if (regex.test(elements)) {
      event.preventDefault ? event.preventDefault() : event.returnValue = false;
    }
  }
}

もちろん、 "INPUT、TEXTAREA"を使用して、 "if(!regex.test(elements))"を使用することもできます。最初は私にとってはうまくいきました。


1

パフォーマンス?

私はパフォーマンスが心配でいじくり回しました:http : //jsfiddle.net/felvhage/k2rT6/9/embedded/result/

var stresstest = function(e, method, index){...

このスレッドで見つけた最も有望な方法を分析しました。結局のところ、それらはすべて非常に高速であり、タイピング時に「緩み」の点で問題を引き起こすことはほとんどありません。私が調べた最も遅い方法は、IE8の10.000コールで約125ミリ秒でした。ストロークあたり0.0125msです。

CodenepalとRobin Mabenによって投稿されたメソッドは最速〜0.001ms(IE8)であることがわかりましたが、異なるセマンティクスに注意してください。

おそらくこれは、この種の機能を自分のコードに導入する誰かにとっての救済です。


1

変更されたエリッカレンの回答:

$(document).unbind('keydown').bind('keydown', function (event) {

    var doPrevent = false, elem;

    if (event.keyCode === 8) {
        elem = event.srcElement || event.target;
        if( $(elem).is(':input') ) {
            doPrevent = elem.readOnly || elem.disabled;
        } else {
            doPrevent = true;
        }
    }

    if (doPrevent) {
        event.preventDefault();
        return false;
    }
});

1
完璧な答え。私が他から得た解決策はFirefoxでは機能しませんでしたが、これは3つすべて(Firefox、IE、Crome)で問題なく完全に機能しました。Proziに感謝します。
Nikhil Dinesh 2014

1

テストすると、このソリューションは非常にうまく機能しました。

入力でタグ付けされていない一部の入力フィールドを処理し、ジョブの入力フォームを生成するOracle PL / SQLアプリケーションに統合するコードを追加しました。

私の「2セント」:

 if (typeof window.event != ''undefined'')
    document.onkeydown = function() {
    //////////// IE //////////////
    var src = event.srcElement;
    var tag = src.tagName.toUpperCase();
    if (event.srcElement.tagName.toUpperCase() != "INPUT"
        && event.srcElement.tagName.toUpperCase() != "TEXTAREA"
        || src.readOnly || src.disabled 
        )
        return (event.keyCode != 8);
    if(src.type) {
       var type = ("" + src.type).toUpperCase();
       return type != "CHECKBOX" && type != "RADIO" && type != "BUTTON";
       }
   }
else
   document.onkeypress = function(e) {
   //////////// FireFox 
   var src = e.target;
   var tag = src.tagName.toUpperCase();
   if ( src.nodeName.toUpperCase() != "INPUT" && tag != "TEXTAREA"
      || src.readOnly || src.disabled )
      return (e.keyCode != 8);
    if(src.type) {
      var type = ("" + src.type).toUpperCase();
      return type != "CHECKBOX" && type != "RADIO" && type != "BUTTON";
      }                              
   }

1

現在受け入れられている(erikkallenの)クリーンバージョンのNPMプロジェクトを作成しました

https://github.com/slorber/backspace-disabler

基本的に同じ原則を使用しますが、

  • 依存関係なし
  • contenteditableのサポート
  • より読みやすく保守しやすいコードベース
  • 自社での生産に使用されるため、サポートされます
  • MITライセンス

var Backspace = 8;

// See http://stackoverflow.com/questions/12949590/how-to-detach-event-in-ie-6-7-8-9-using-javascript
function addHandler(element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + type, handler);
    } else {
        element["on" + type] = handler;
    }
}
function removeHandler(element, type, handler) {
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
        element.detachEvent("on" + type, handler);
    } else {
        element["on" + type] = null;
    }
}




// Test wether or not the given node is an active contenteditable,
// or is inside an active contenteditable
function isInActiveContentEditable(node) {
    while (node) {
        if ( node.getAttribute && node.getAttribute("contenteditable") === "true" ) {
            return true;
        }
        node = node.parentNode;
    }
    return false;
}



var ValidInputTypes = ['TEXT','PASSWORD','FILE','EMAIL','SEARCH','DATE'];

function isActiveFormItem(node) {
    var tagName = node.tagName.toUpperCase();
    var isInput = ( tagName === "INPUT" && ValidInputTypes.indexOf(node.type.toUpperCase()) >= 0 );
    var isTextarea = ( tagName === "TEXTAREA" );
    if ( isInput || isTextarea ) {
        var isDisabled = node.readOnly || node.disabled;
        return !isDisabled;
    }
    else if ( isInActiveContentEditable(node) ) {
        return true;
    }
    else {
        return false;
    }
}


// See http://stackoverflow.com/questions/1495219/how-can-i-prevent-the-backspace-key-from-navigating-back
function disabler(event) {
    if (event.keyCode === Backspace) {
        var node = event.srcElement || event.target;
        // We don't want to disable the ability to delete content in form inputs and contenteditables
        if ( isActiveFormItem(node) ) {
            // Do nothing
        }
        // But in any other cases we prevent the default behavior that triggers a browser backward navigation
        else {
            event.preventDefault();
        }
    }
}


/**
 * By default the browser issues a back nav when the focus is not on a form input / textarea
 * But users often press back without focus, and they loose all their form data :(
 *
 * Use this if you want the backspace to never trigger a browser back
 */
exports.disable = function(el) {
    addHandler(el || document,"keydown",disabler);
};

/**
 * Reenable the browser backs
 */
exports.enable = function(el) {
    removeHandler(el || document,"keydown",disabler);
};

1

これがトップ投票の回答の私の書き直しです。element.value!== undefinedをチェックしようとしました(たとえば、html属性がなくても、プロトタイプチェーンのどこかにjavascriptのvalueプロパティがある可能性があるため)。これを将来にわたって保証するための良い方法はないようですので、ホワイトリストが最良のオプションのようです。

これにより、イベントバブルフェーズの最後に要素が登録されるため、任意のカスタム方法でBackspaceを処理したい場合は、他のハンドラーで行うことができます。

これは、HTMLTextAreElementのインスタンスもチェックします。理論的には、それから継承するWebコンポーネントがあるためです。

これはcontentEditableをチェックしません(他の回答と組み合わせる)。

https://jsfiddle.net/af2cfjc5/15/

var _INPUTTYPE_WHITELIST = ['text', 'password', 'search', 'email', 'number', 'date'];

function backspaceWouldBeOkay(elem) {
    // returns true if backspace is captured by the element
    var isFrozen = elem.readOnly || elem.disabled;
    if (isFrozen) // a frozen field has no default which would shadow the shitty one
        return false;
    else {
        var tagName = elem.tagName.toLowerCase();
        if (elem instanceof HTMLTextAreaElement) // allow textareas
            return true;
        if (tagName=='input') { // allow only whitelisted input types
            var inputType = elem.type.toLowerCase();
            if (_INPUTTYPE_WHITELIST.includes(inputType))
                return true;
        }   
        return false; // everything else is bad
    }
}

document.body.addEventListener('keydown', ev => {
    if (ev.keyCode==8 && !backspaceWouldBeOkay(ev.target)) {
        //console.log('preventing backspace navigation');
        ev.preventDefault();
    }
}, true); // end of event bubble phase

0

Sitepoint:JavaScriptの無効化

event.stopPropagation()そして、event.preventDefault()IEで何もしません。しかし、私はそれを機能させるためevent.keyCode == 11に単に言うのではなく、返送(私は何かを選んだだけ)をしなければなり"if not = 8, run the event"ませんでした。 event.returnValue = falseも動作します。


0

jqueryを使用する別の方法

    <script type="text/javascript">

    //set this variable according to the need within the page
    var BACKSPACE_NAV_DISABLED = true;

    function fnPreventBackspace(event){if (BACKSPACE_NAV_DISABLED && event.keyCode == 8) {return false;}}
    function fnPreventBackspacePropagation(event){if(BACKSPACE_NAV_DISABLED && event.keyCode == 8){event.stopPropagation();}return true;}

    $(document).ready(function(){ 
        if(BACKSPACE_NAV_DISABLED){
            //for IE use keydown, for Mozilla keypress  
            //as described in scr: http://www.codeproject.com/KB/scripting/PreventDropdownBackSpace.aspx
            $(document).keypress(fnPreventBackspace);
            $(document).keydown(fnPreventBackspace);

            //Allow Backspace is the following controls 
            var jCtrl = null;
            jCtrl = $('input[type="text"]');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            jCtrl = $('input[type="password"]');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            jCtrl = $('textarea');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            //disable backspace for readonly and disabled
            jCtrl = $('input[type="text"][readonly="readonly"]')
            jCtrl.keypress(fnPreventBackspace);
            jCtrl.keydown(fnPreventBackspace);

            jCtrl = $('input[type="text"][disabled="disabled"]')
            jCtrl.keypress(fnPreventBackspace);
            jCtrl.keydown(fnPreventBackspace);
        }
    }); 

    </script>

コントロール(テキストボックス)が動的に追加されている場合、これは機能しないことに注意してください。
CodeNepal 2011

0

これをコードでしばらく使用しています。私は学生向けのオンラインテストを作成し、学生がテスト中にバックスペースを押していたときに問題に遭遇し、ログイン画面に戻りました。イライラ!それは確かにFFで動作します。

document.onkeypress = Backspace;
function Backspace(event) {
    if (event.keyCode == 8) {
        if (document.activeElement.tagName == "INPUT") {
            return true;
        } else {
            return false;
        }
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.