it-swarm.com.de

Wie kann ich verhindern, dass die Rücktaste zurück navigiert?

On IE Ich kann das mit der (fürchterlich nicht standardmäßigen, aber funktionierenden) jQuery machen

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

Aber ist es möglich, auf eine Weise zu arbeiten, die unter Firefox funktioniert, oder auf eine browserübergreifende Weise, um einen Bonus zu erhalten?

Für die Aufzeichnung:

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

tut nichts.

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

behebt das Problem, macht jedoch die Rücktaste auf der Seite unbrauchbar, was sogar noch schlimmer ist als das ursprüngliche Verhalten.

BEARBEITEN: Der Grund dafür ist, dass ich keine einfache Webseite erstelle, sondern eine große Anwendung. Es ist unglaublich ärgerlich, 10 Minuten Arbeit zu verlieren, nur weil Sie die Rücktaste an der falschen Stelle gedrückt haben. Das Verhältnis von Verhindern von Fehlern zu ärgerlichen Benutzern sollte weit über 1000/1 liegen, indem verhindert wird, dass die Rücktaste zurück navigiert.

EDIT2: Ich versuche nicht , die Verlaufsnavigation zu verhindern, sondern nur Unfälle.

EDIT3: @brentonstrines Kommentar (hierher verschoben, da die Frage so populär ist): Dies ist eine langfristige 'Korrektur', aber Sie könnten Ihre Unterstützung hinter das Chromium-Bug, um dieses Verhalten im Webkit zu ändern werfen

266
erikkallen

Dieser Code löst das Problem, zumindest in IE und Firefox (habe noch keinen anderen getestet, aber ich gebe ihm eine vernünftige Chance zu arbeiten, wenn das Problem sogar in anderen Browsern besteht).

// 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;
        }
    }
});
326
erikkallen

Dieser Code funktioniert in allen Browsern und verschluckt die Rücktaste, wenn kein Formularelement vorhanden ist oder wenn das Formularelement | readOnly deaktiviert ist. Es ist auch effizient, was wichtig ist, wenn es auf jedem eingegebenen Schlüssel ausgeführt wird.

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

Die anderen Antworten hier haben gezeigt, dass dies nicht ohne Whitelist-Elemente möglich ist, in denen die Rücktaste zulässig ist. Diese Lösung ist nicht ideal, da die Whitelist nicht so einfach wie nur Textbereiche und Text-/Passworteingaben ist, sondern immer wieder als unvollständig befunden wird und aktualisiert werden muss.

Da der Zweck der Unterdrückung der Backspace-Funktionalität lediglich darin besteht, zu verhindern, dass Benutzer versehentlich Daten verlieren, ist die Lösung vor dem Laden eine gute Lösung, da das modale Popup überraschend ist - modale Popups sind schlecht, wenn sie als Teil eines Standardworkflows ausgelöst werden. weil sich der Benutzer daran gewöhnt, sie zu verwerfen, ohne sie zu lesen, und sie nerven. In diesem Fall wird das modale Popup nur als Alternative zu einer seltenen und überraschenden Aktion angezeigt und ist daher akzeptabel.

Das Problem ist, dass ein Onbeforeunload-Modal nicht angezeigt werden darf, wenn der Benutzer von der Seite weg navigiert (z. B. wenn er auf einen Link klickt oder ein Formular absendet), und wir nicht mit der Whitelist oder Blacklisting bestimmter Onbeforeunload-Bedingungen beginnen möchten.

Die ideale Kombination von Kompromissen für eine verallgemeinerte Lösung lautet wie folgt: Verfolgen Sie, ob die Rücktaste gedrückt ist, und rufen Sie das Onbeforeunload-Modal nur auf, wenn dies der Fall ist. Mit anderen Worten:

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

Dies wurde getestet, um in IE7 +, FireFox, Chrome, Safari und Opera zu funktionieren. Fügen Sie diese Funktion einfach in Ihre Datei global.js ein und rufen Sie sie auf einer beliebigen Seite auf, auf der Benutzer nicht versehentlich ihre Daten verlieren sollen.

Beachten Sie, dass dies nicht bei Hash-Änderungsereignissen ausgelöst wird. In diesem Kontext können Sie jedoch andere Techniken verwenden, um zu verhindern, dass Benutzer versehentlich ihre Daten verlieren.

41
Vladimir Kornea

Eine elegantere/prägnantere Lösung:

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

Änderung der Antwort von erikkallen, um verschiedene Eingabetypen anzusprechen

Ich habe festgestellt, dass ein unternehmungslustiger Benutzer möglicherweise die Rücktaste eines Kontrollkästchens oder eines Optionsfelds drückt, um es zu löschen. Stattdessen navigiert er rückwärts und verliert alle seine Daten.

Diese Änderung sollte dieses Problem beheben.

Neue Bearbeitung, um bearbeitbare Divs zu adressieren

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

Beispiel
Zum Testen 2 Dateien erstellen.

starthere.htm - öffne dies zuerst, damit du einen Ort hast, zu dem du zurückkehren kannst

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

test.htm - Dies wird rückwärts navigieren, wenn die Rücktaste gedrückt wird, während das Kontrollkästchen oder die Übermittlung den Fokus hat (erreicht durch Tabulieren). Ersetzen Sie mit meinem Code, um zu beheben.

<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

Basierend auf den Kommentaren scheint es, dass Sie verhindern möchten, dass Benutzer Informationen in Formularen verlieren, wenn sie zum Löschen die Rücktaste drücken, das Feld jedoch nicht fokussiert ist.

In diesem Fall möchten Sie sich den Ereignishandler onunload ansehen. Stack Overflow verwendet es. Wenn Sie versuchen, eine Seite zu verlassen, während Sie mit dem Schreiben einer Antwort begonnen haben, wird eine Warnung angezeigt.

8
DisgruntledGoat

Hören Sie auf, in diesem Code zu navigieren!

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

Aber nicht um Textfelder einzuschränken, sondern um andere

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

Um dies für ein bestimmtes Feld zu verhindern, verwenden Sie einfach

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

Unter Bezugnahme auf dieses unten!

Verhindern, dass BACKSPACE mit jQuery (wie Googles Homepage) zurück navigiert

7

Die meisten Antworten sind in Frage. Sie können dies perfekt in reinem Javascript, einfach und ohne Bibliothek tun. Dieser Artikel war ein guter Ausgangspunkt für mich, aber da keyIdentifier veraltet ist, wollte ich, dass dieser Code sicherer ist, damit ich || e.keyCode == 8 zur if-Anweisung hinzugefügt. Außerdem hat der Code in Firefox nicht gut funktioniert, also habe ich return false hinzugefügt und jetzt funktioniert er einwandfrei. Hier ist es:

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

Dieser Code funktioniert hervorragend, weil

  1. Es ist in reinem Javascript (keine Bibliothek erforderlich).
  2. Es wird nicht nur die gedrückte Taste überprüft, sondern auch bestätigt, ob es sich bei der Aktion tatsächlich um eine Browser-Zurück-Aktion handelt.
  3. Zusammen mit dem oben Gesagten kann der Benutzer problemlos Text in die Eingabetextfelder auf der Webseite eingeben und löschen, ohne die Aktion der Schaltfläche "Zurück" zu beeinträchtigen.
  4. Es ist kurz, sauber, schnell und direkt auf den Punkt.

Sie können console.log (e) hinzufügen. Für Ihre Testzwecke drücken Sie F12 in Chrom, gehen Sie zur Registerkarte "Konsole" und drücken Sie die Rücktaste auf der Seite, um zu sehen, welche Werte zurückgegeben werden. Anschließend können Sie alle diese Parameter gezielt verwenden, um den Code weiter zu verbessern oben, um Ihren Bedürfnissen zu entsprechen.

6
Tarik

Kombinieren von Lösungen von "thetoolman" && "Biff MaGriff"

der folgende Code scheint in IE 8/Mozilla/Chrome korrekt zu funktionieren

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

Ich bin mir nicht sicher, warum niemand diese Frage beantwortet hat - es scheint eine vernünftige technische Frage zu sein, ob dies möglich ist.

Nein, ich glaube nicht, dass es eine browserübergreifende Möglichkeit gibt, die Rücktaste zu deaktivieren. Ich weiß, dass es heutzutage in FF nicht standardmäßig aktiviert ist.

5
brabster

JavaScript - jQuery Weg:

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

Javascript - der native Weg, der bei mir funktioniert:

<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

Diese Lösung ähnelt anderen veröffentlichten Lösungen, verwendet jedoch eine einfache Whitelist, die es einfach macht, die Rücktaste in angegebenen Elementen anzupassen, indem Sie den Selektor in der Funktion .is () festlegen.

Ich benutze es in dieser Form, um zu verhindern, dass der Backspace auf Seiten zurücknavigiert:

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

Es fiel mir schwer, eine Non-JQUERY-Antwort zu finden. Vielen Dank an Stas, der mich auf die Strecke gebracht hat.

Chrome: Wenn Sie keine browserübergreifende Unterstützung benötigen, können Sie statt Whitelisting nur eine Blacklist verwenden. Diese reine JS-Version funktioniert in Chrome, aber nicht im IE. Ich bin mir nicht sicher über FF.

In Chrome (ver. 36, mitte 2014)) scheinen Tastendrücke, die sich nicht auf eine Eingabe oder ein inhaltsbearbeitbares Element beziehen, auf <BODY> Abzustellen. Dies ermöglicht die Verwendung einer Blacklist, die ich verwende ziehe Whitelisting vor. IE verwendet das Ziel für den letzten Klick - es könnte also ein Div oder etwas anderes sein. Das macht dies im IE nutzlos.

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

Cross Browser: Für reines Javascript fand ich die Antwort von Stas die beste. Das Hinzufügen einer weiteren Bedingungsprüfung für contenteditable hat für mich funktioniert *:

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

* Beachten Sie, dass IEs [edit: und Spartan/TechPreview] eine "Funktion" haben, die tabellenbezogene Elemente nicht editierbar macht . Wenn Sie auf eine davon klicken und dann die Rücktaste drücken, navigiert sie zurück. Wenn Sie keine bearbeitbaren <td> Haben, ist dies kein Problem.

3
Josiah

Um etwas auf @ erikkallens ausgezeichnete Antwort einzugehen, hier eine Funktion, die alle tastaturbasierten Eingabetypen erlaubt, einschließlich die in HTML5 eingeführten :

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

Ich hatte einige Probleme mit der akzeptierten Lösung und dem Select2.js-Plugin. Ich konnte keine Zeichen in der bearbeitbaren Box löschen, da die Löschaktion verhindert wurde. Das war meine Lösung:

//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 erstellt einen Span mit dem Attribut "contentEditable", das für das bearbeitbare Kombinationsfeld auf "true" gesetzt ist. Ich habe Code hinzugefügt, um die Bereiche tagName und das andere Attribut zu berücksichtigen. Dies löste alle meine Probleme.

Bearbeiten: Wenn Sie das Select2-Combobox-Plugin nicht für JQuery verwenden, wird diese Lösung möglicherweise nicht von Ihnen benötigt, und die akzeptierte Lösung ist möglicherweise besser.

2
Pytry

Mit Dojo Toolkit 1.7 funktioniert dies in 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

Geänderte erikkallen Antwort:

$(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
Jacek Pietal
    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

Eine viel sauberere Lösung -

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

Alternativ können Sie nur prüfen, ob

$(document.activeElement).is('body')
1
Robin Maben

Dieser Code löst das Problem in allen Browsern:

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

Hier ist mein Umschreiben der am häufigsten gewählten Antwort. Ich habe versucht, element.value! == undefined zu überprüfen (da einige Elemente wie kein HTML-Attribut haben, aber möglicherweise irgendwo in der Prototypenkette eine Javascript-Werteigenschaft haben), aber das funktionierte nicht sehr gut und hatte viele Edge-Fälle. Es scheint keinen guten Weg zu geben, um dies zukunftssicher zu machen. Daher scheint eine Whitelist die beste Option zu sein.

Dadurch wird das Element am Ende der Ereignisblasenphase registriert. Wenn Sie also die Rücktaste auf eine benutzerdefinierte Weise behandeln möchten, können Sie dies in anderen Handlern tun.

Dies überprüft auch die Instanz von HTMLTextAreElement, da man theoretisch eine Webkomponente haben könnte, die davon erbt.

Dies überprüft nicht contentEditable (mit anderen Antworten kombinieren).

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

Diese Lösung hat im Test sehr gut funktioniert.

Ich habe Code hinzugefügt, um einige Eingabefelder zu verarbeiten, die nicht mit Eingabe gekennzeichnet sind, und um sie in eine Oracle PL/SQL-Anwendung zu integrieren, die ein Eingabeformular für meinen Job generiert.

Meine zwei Cent":

 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

Haben Sie die sehr einfache Lösung ausprobiert, einfach das folgende Attribut in Ihr schreibgeschütztes Textfeld einzufügen:

onkeydown = "return false;"

Dadurch wird verhindert, dass der Browser in den Verlauf zurückkehrt, wenn die Rücktaste in einem schreibgeschützten Textfeld gedrückt wird. Vielleicht fehlt mir Ihre wahre Absicht, aber dies scheint die einfachste Lösung für Ihr Problem zu sein.

1
B-Dog

Reine Javascript-Version, die in allen Browsern funktioniert:

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

Natürlich können Sie "INPUT, TEXTAREA" und dann "if (! Regex.test (elements))" verwenden. Die erste hat gut funktioniert für mich.

Ich habe ein NPM-Projekt mit einer sauberen Version der aktuell akzeptierten (von erikkallen) erstellt.

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

Es verwendet im Grunde die gleichen Prinzipien, aber:

  • Keine Abhängigkeit
  • Unterstützung für Contenteditable
  • Besser lesbare/wartbare Codebasis
  • Wird unterstützt, da es von meiner Firma in der Produktion verwendet wird
  • MIT-Lizenz

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

Einfachste Möglichkeit, die Navigation beim Drücken der Rücktaste zu verhindern

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

Leistung?

Ich war besorgt über die Leistung und machte eine Geige: http://jsfiddle.net/felvhage/k2rT6/9/embedded/result/

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

Ich habe die vielversprechendsten Methoden analysiert, die ich in diesem Thread gefunden habe. Es stellt sich heraus, dass sie alle sehr schnell waren und höchstwahrscheinlich kein Problem in Bezug auf "Trägheit" beim Tippen verursachen. Die langsamste Methode, die ich mir angesehen habe, war ungefähr 125 ms für 10.000 Anrufe im IE8. Welches ist 0,0125 ms pro Hub.

Ich fand die Methoden von Codenepal und Robin Maben am schnellsten ~ 0,001 ms (IE8), aber hüte dich vor der unterschiedlichen Semantik.

Vielleicht ist dies eine Erleichterung für jemanden, der diese Art von Funktionalität in seinen Code einführt.

1
felvhage

Für alle Interessierten habe ich ein jQuery-Plugin zusammengestellt, das die obigen Ideen von thetoolman (plus @ MaffooClock/@ cdmckay) und @ Vladimir Kornea enthält .

Verwendungszweck:

//# 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"
});

Plugin:

//# 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

Ich benutze dies seit einiger Zeit in meinem Code. Ich schreibe Online-Tests für Studenten und bin auf das Problem gestoßen, als die Studenten während des Tests die Rücktaste gedrückt haben und sie dann zum Anmeldebildschirm zurückkehrten. Frustrierend! Es funktioniert auf jeden Fall auf FF.

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

Eine andere Methode mit 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

Hat für mich gearbeitet

<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

Alle bisher gegebenen Antworten konzentrieren sich auf das Skripting des Fixes in die Webseite. Aber was ist, wenn ich das Feature einfach für mich selbst haben möchte, ohne andere Benutzer zu beeinträchtigen?

In diesem Fall ist eine Lösung für den Browser selbst vorzuziehen:
- Firefox unter Linux hat das Backspace-Verhalten seit 2006 "aufgehoben", damit es nicht beeinträchtigt wird. (Jedenfalls war es einfach so eingestellt, dass es vorher hochscrollte)
- Chrome hat gerade angekündigt, dass es von nun an dasselbe tun wird; ( http://forums.theregister.co.uk/forum/1/ 2016/05/20/chrome_deletes_backspace / )
- Firefox unter Windows kann so eingestellt werden, dass die Rücktaste ignoriert wird. Gehen Sie dazu folgendermaßen vor: config und ändern Sie die Einstellung für backspace_action auf 2; ( http://kb.mozillazine.org/Browser.backspace_action )
- Safari?!

0
Paolo

Sitepoint: Zurück für Javascript deaktivieren

event.stopPropagation() und event.preventDefault() machen im IE nichts. Ich musste einen Return senden event.keyCode == 11 (Ich habe gerade etwas ausgewählt), anstatt nur "if not = 8, run the event" Zu sagen, damit es funktioniert. event.returnValue = false Funktioniert auch.

0
Tom