web-dev-qa-db-ja.com

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

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(); });

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

編集:私がこれをする理由は私が単純なウェブページを作成するのではなく大規模なアプリケーションを作成するということです。間違った場所でバックスペースを押したからといって、10分の作業時間を失うのは非常に面倒です。ミスを防ぐ対煩わしいユーザーの比率は、バックスペースキーが元に戻らないようにすることで1000/1をはるかに超えるはずです。

編集2:私はしない歴史のナビゲーションを防ぐことを試みている、ただの事故。

EDIT3:@brentonstrinesコメント(この質問はとても人気があるのでここに移動しました):これは長期的な '修正'ですが、あなたはサポートを背後に投げ捨てることができます webkitでこの動作を変更するChromiumのバグ

266
erikkallen

このコードは、少なくとも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;
        }
    }
});
323
erikkallen

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

$(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();
            }
        }
    });
});
60
thetoolman

ここでの他の答えは、Backspaceが許可されている要素をホワイトリストに載せずにこれを行うことはできないことを証明しています。ホワイトリストは単なるテキストエリアやテキスト/パスワードの入力ほど単純ではありませんが、不完全で更新が必要であることが繰り返し確認されるため、このソリューションは理想的ではありません。

ただし、バックスペース機能を抑止する目的はユーザーが誤ってデータを失うのを防ぐことだけであるため、モーダルポップアップは驚くべきことです。つまり、モーダルポップアップは標準ワークフローの一部としてトリガーされるのは悪いためです。ユーザーがそれらを読むことなくそれらを却下することに慣れ、そして彼らは煩わしいからです。この場合、モーダルポップアップはまれで驚くべき動作の代替として表示されるだけなので、受け入れられます。

問題は、ユーザーがページから移動したとき(リンクをクリックしたりフォームを送信したときなど)に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にドロップして、ユーザーが誤ってデータを失ってほしくないページから呼び出すだけです。

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

40
Vladimir Kornea

よりエレガントで簡潔な解決策:

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

さまざまな入力タイプに対処するための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();
    });


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>
15
Biff MaGriff

コメントに基づいて、削除するためにバックスペースを押したがフィールドがフォーカスされていない場合、フォーム内の情報を失うのを止めたいと思うでしょう。

その場合は、onunloadイベントハンドラを見てください。 Stack Overflowはそれを使用します - あなたが答えを書き始めたときにあなたがページを離れようとすると、それは警告をポップアップします。

8
DisgruntledGoat

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

$(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でこれを完全に行うことができます。シンプルでライブラリは不要です。 This 記事は私にとって良い出発点でしたが、keyIdentifierは廃止予定なので、このコードをより安全にしたいのでifステートメントに|| e.keyCode == 8を追加しました。また、コードが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. 上記と合わせて、ユーザは、戻るボタンの動作を依然として防止しながら、問題なくウェブページ上の入力テキストボックスからテキストを入力および削除することができる。
  4. それは短くて、きれいで、速くて、そしてポイントまでまっすぐです。

Console.log(e)を追加することができます。あなたのテスト目的のために、そしてクロムでF12キーを押して、ページ上で「コンソール」タブに行き、そして「backspace」を押してどんな値が返されるかを見るためにそれからあなたはコードをさらに強化するためにこれらのパラメータのすべてを目標とすることができるあなたのニーズに合うように上記の。

5
Tarik

"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();
    });
}); 
5
CodeNepal

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

いいえ、バックスペースボタンを無効にするクロスブラウザの方法はないと思います。最近のFFでは、デフォルトでは有効になっていません。

5
brabster

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>
3

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

このフォームでは、ページ上のバックスペースが元に戻らないようにするために使用します。

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

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

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

Chrome(ver。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 [edit:and Spartan/TechPreview]には、 テーブル関連の要素を編集不可能な にする「機能」があります。あなたがそれらのうちの1つをクリックするならば、そしてそれがバックスペースを押すならば、それは後ろにナビゲートするでしょう。編集可能な<td>sがなければ、これは問題にはなりません。

3
Josiah

@ 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();
    }
});
3
Gingi

承認されたソリューションと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は、その中の編集可能なコンボボックスに対してtrueに設定されている "contentEditable"の属性でSpanを作成します。スパンtagNameと異なる属性を考慮してコードを追加しました。これで私の問題はすべて解決した。

編集:あなたがjqueryのためにSelect2コンボボックスプラグインを使用していないなら、この解決策はあなたによって必要とされないかもしれません、そして受け入れられた解決策はより良いかもしれません。

2
Pytry

Dojo toolkit 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
Chris V

修正されたエリッカレン回答:

$(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
Prozi
    document.onkeydown = function (e) {    
        e.stopPropagation();
        if ((e.keyCode==8  ||  e.keyCode==13) &&
            (e.target.tagName != "TEXTAREA") && 
            (e.target.tagName != "INPUT")) { 
            return false;
        }
    };
1
elico3000

非常に優れた解決策 -

$(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
Robin Maben

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

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
Haseeb Akhtar

これは私がトップ投票の答えを書き直したものです。 element.value!== undefinedをチェックしようとしました(html属性を持たないがプロトタイプチェーンのどこかにjavascript valueプロパティを持つような要素があるため)が、あまりうまく機能せず、Edgeのケースがたくさんありました。これを将来を保証する良い方法はないようですので、ホワイトリストが最善の選択肢のようです。

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

理論的にはそれを継承するWebコンポーネントを持つことができるので、これはHTMLTextAreElementのinstanceもチェックします。

これは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
1
ninjagecko

このソリューションはテスト時に非常にうまくいきました。

入力タグが付いていない入力フィールドを処理し、仕事用の入力フォームを生成する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
Luis Cuellar

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

onkeydown = "falseを返します。"

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

1
B-Dog

すべてのブラウザで機能する純粋な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))"を使用することもできます。最初はうまくいった。

私は、現在受け入れられている(erikkallenの)クリーン版でNPMプロジェクトを作成しました。

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

それは基本的に同じ原則を使用しますが:

  • 依存関係なし
  • 満足できるもののサポート
  • 読みやすく保守しやすいコードベース
  • それは私の会社によって生産で使用されるのでサポートされます
  • 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

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

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

パフォーマンスは?

私はパフォーマンスを心配していたし、フィドルを作りました: http://jsfiddle.net/felvhage/k2rT6/9/embedded/result/

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

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

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

おそらくこれは、この種の機能を自分のコードに導入した人にとっては安心です。

1
felvhage

興味のある人のために、 thetoolman (プラス@ MaffooClock/@ cdmckayのコメント)と@ Vladimir Kornea のアイデアを組み込んだjQueryプラグインをまとめました。 。

使用法:

//# Disable backspace on .disabled/.readOnly fields for the whole document
$(document).disableBackspaceNavigation();

//# Disable backspace on .disabled/.readOnly fields under FORMs
$('FORM').disableBackspaceNavigation();

//# Disable backspace on .disabled/.readOnly fields under #myForm
$('#myForm').disableBackspaceNavigation();

//# Disable backspace on .disabled/.readOnly fields for the whole document with confirmation
$(document).disableBackspaceNavigation(true);

//# Disable backspace on .disabled/.readOnly fields for the whole document with all options
$(document).disableBackspaceNavigation({
    confirm: true,
    confirmString: "Are you sure you want to navigate away from this page?",
    excludeSelector: "input, select, textarea, [contenteditable='true']",
    includeSelector: ":checkbox, :radio, :submit"
});

プラグイン

//# Disables backspace initiated navigation, optionally with a confirm dialog
//#     From: https://stackoverflow.com/questions/1495219/how-can-i-prevent-the-backspace-key-from-navigating-back
$.fn.disableBackspaceNavigation = function (vOptions) {
    var bBackspaceWasPressed = false,
        o = $.extend({
            confirm: (vOptions === true),   //# If the caller passed in `true` rather than an Object, default .confirm accordingly,
            confirmString: "Are you sure you want to leave this page?",
            excludeSelector: "input, select, textarea, [contenteditable='true']",
            includeSelector: ":checkbox, :radio, :submit"
        }, vOptions)
    ;

    //# If we are supposed to use the bConfirmDialog, hook the beforeunload event
    if (o.confirm) {
        $(window).on('beforeunload', function () {
            if (bBackspaceWasPressed) {
                bBackspaceWasPressed = false;
                return o.confirmString;
            }
        });
    }

    //# Traverse the passed elements, then return them to the caller (enables chainability)
    return this.each(function () {
        //# Disable backspace on disabled/readonly fields
        $(this).bind("keydown keypress", function (e) {
            var $target = $(e.target /*|| e.srcElement*/);

            //# If the backspace was pressed
            if (e.which === 8 /*|| e.keyCode === 8*/) {
                bBackspaceWasPressed = true;

                //# If we are not using the bConfirmDialog and this is not a typeable input (or a non-typeable input, or is .disabled or is .readOnly), .preventDefault
                if (!o.confirm && (
                    !$target.is(o.excludeSelector) ||
                    $target.is(o.includeSelector) ||
                    e.target.disabled ||
                    e.target.readOnly
                )) {
                    e.preventDefault();
                }
            }
        });
    });
}; //# $.fn.disableBackspaceNavigation
0
Campbeln

私はしばらくの間私のコードでこれを使っています。私は学生のためにオンラインテストを書き、学生がテスト中に後退を押していたときに問題に遭遇しました、そしてそれはログインスクリーンにそれらを連れ戻すでしょう。イライラする!確かにFF上で動作します。

document.onkeypress = Backspace;
function Backspace(event) {
    if (event.keyCode == 8) {
        if (document.activeElement.tagName == "INPUT") {
            return true;
        } else {
            return false;
        }
    }
}
0
Tan

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>
0
CodeNepal

私のために働いた

<script type="text/javascript">


 if (typeof window.event != 'undefined')
    document.onkeydown = function()
    {
        if (event.srcElement.tagName.toUpperCase() != 'INPUT')
            return (event.keyCode != 8);
    }
else
    document.onkeypress = function(e)
    {
        if (e.target.nodeName.toUpperCase() != 'INPUT')
            return (e.keyCode != 8);
    }

</script>
0
Pieter de Vries

これまでの回答はすべてWebページへの修正のスクリプティングに焦点を当てていましたが、他のユーザーに影響を与えずに単に自分自身のための機能を使用したい場合はどうなりますか?

この場合、ブラウザ自体のための解決策が好まれるべきです:
- Linux上のFirefoxは2006年以来バックスペースの振る舞いを「マップ解除」していたので影響はありません。 (とにかく、それはそれ以前に単に上にスクロールするように設定されていました)
- Chromeは、今後も同じことを行うと発表した。 ( http://forums.theregister.co.uk/forum/1/2016/05/20/chrome_deletes_backspace/
- Windows上のFirefoxは、about:configに入りbackspace_action設定を2に変更することで、バックスペースを無視するように設定できます。 ( http://kb.mozillazine.org/Browser.backspace_action
- サファリ?

0
Paolo

Sitepoint:Javascriptを無効にする

event.stopPropagation()event.preventDefault()はIEでは何もしません。ただし、それを機能させるには、単にevent.keyCode == 11と言う代わりに、"if not = 8, run the event"を返す必要がありました。 event.returnValue = falseも動作します。

0
Tom