Jak zapobiec cofaniu się klawisza backspace?

Na IE mogę to zrobić z (strasznie niestandardowym, ale działającym) jQuery

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

Ale czy można zrobić w sposób, który działa na Firefoksie, lub w sposób między przeglądarkowy dla premii?

Dla przypomnienia:

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

Rozwiązuje problem, ale powoduje, że klawisz backspace jest bezużyteczny na stronie, co jest jeszcze gorsze niż pierwotne zachowanie.

Edytuj: Powodem, dla którego to robię, jest to, że nie tworzę prostej strony internetowej, ale dużą podanie. To niesamowicie denerwujące stracić 10 minut pracy tylko dlatego, że nacisnąłeś backspace w niewłaściwym miejscu. Stosunek zapobiegania błędom do irytujących użytkowników powinien być znacznie wyższy niż 1000/1, zapobiegając cofaniu się klawisza backspace.

EDIT2: ja Nie próbuję zapobiec nawigacji w historii, tylko wypadkom.

EDIT3: @ Brent. comment (przeniesiony tutaj, ponieważ pytanie jest tak popularne): to jest długoterminowe 'fix', ale możesz rzucić swoje poparcie za błąd Chromium, aby zmienić to zachowanie w webkit

Author: John Weisz, 2009-09-30

30 answers

Ten kod rozwiązuje problem, przynajmniej w IE i Firefoksie (nie testowałem żadnego innego, ale daję mu rozsądną szansę na działanie, jeśli problem istnieje nawet w innych przeglądarkach).

// 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;
        }
    }
});
 316
Author: erikkallen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-07 08:01:11

Ten kod działa na wszystkich przeglądarkach i połyka klawisz backspace, gdy nie znajduje się na elemencie formularza lub gdy element formularza jest wyłączony|tylko odczyt. Jest również wydajny, co jest ważne, gdy jest wykonywany na każdym wpisanym kluczu.

$(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();
            }
        }
    });
});
 58
Author: thetoolman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-21 20:49:46

Inne odpowiedzi tutaj ustaliły, że nie można tego zrobić bez elementów z białej listy, w których Backspace jest dozwolone. To rozwiązanie nie jest idealne, ponieważ biała lista nie jest tak prosta, jak tylko tekst i wprowadzanie tekstu/hasła, ale jest wielokrotnie stwierdzane jako niekompletne i wymagające aktualizacji.

Jednak, ponieważ celem tłumienia funkcji backspace jest jedynie zapobieganie przypadkowej utracie danych przez użytkowników, rozwiązanie beforeunload jest dobrym rozwiązaniem jeden, ponieważ modalne popup jest zaskakujące -- modalne popups są złe, gdy są one wyzwalane jako część standardowego przepływu pracy, ponieważ użytkownik przyzwyczaja się do odrzucania ich bez czytania ich, i są denerwujące. W tym przypadku modalne wyskakujące okienko pojawiłoby się tylko jako alternatywa dla rzadkiej i zaskakującej akcji, a zatem jest dopuszczalne.

Problem polega na tym, że modal onbeforeunload nie może pojawiać się za każdym razem, gdy użytkownik przechodzi z dala od strony (np. po kliknięciu linku lub przesyłanie formularza), i nie chcemy rozpoczynać białej lub czarnej listy konkretnych warunków onbeforeunload.

Idealna kombinacja kompromisów dla uogólnionego rozwiązania jest następująca: śledź, czy Backspace jest wciśnięty, i tylko wyskakuj modal onbeforeunload, jeśli tak jest. Innymi słowy:

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

To zostało przetestowane do pracy w IE7+, FireFox, Chrome, Safari i Opera. Po prostu wrzuć tę funkcję do swojego globalnego.js i wywołaj go z dowolnej strony, na której nie chcesz użytkowników do przypadkowej utraty danych.

 39
Author: Vladimir Kornea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-10 17:44:51

Bardziej eleganckie / zwięzłe rozwiązanie:

$(document).on('keydown',function(e){
  var $target = $(e.target||e.srcElement);
  if(e.keyCode == 8 && !$target.is('input,[contenteditable="true"],textarea'))
  {
    e.preventDefault();
  }
})
 22
Author: Darwayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-25 12:17:13

Modyfikacja odpowiedzi erikkallen na różne typy wejść

Odkryłem, że przedsiębiorczy użytkownik może nacisnąć backspace na checkbox lub przycisk radiowy w próżnej próbie wyczyszczenia go i zamiast tego będą poruszać się do tyłu i stracić wszystkie swoje dane.

Ta zmiana powinna rozwiązać ten problem.

New Edit to address content editable divs

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

Przykład
Aby przetestować make 2 pliki.

/ Align = "left" / htm - otwórz najpierw to, aby mieć gdzie wrócić
<a href="./test.htm">Navigate to here to test</a>

Test.htm-to będzie poruszać się do tyłu Po naciśnięciu backspace, podczas gdy pole wyboru lub wyślij ma fokus (osiągnięty przez tabbing). Zastąp moim kodem, aby naprawić.

<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
Author: Biff MaGriff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 23:01:04

Na podstawie komentarzy wygląda na to, że chcesz powstrzymać ludzi od utraty informacji w formularzach, jeśli nacisną backspace, aby usunąć, ale Pole nie jest skupione.

W takim przypadku należy spojrzeć na obsługę zdarzenia onunload . Używa tego Stack Overflow - jeśli spróbujesz opuścić stronę po rozpoczęciu pisania odpowiedzi, wyświetli się Ostrzeżenie.

 8
Author: DisgruntledGoat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-29 23:23:39

Przestań nawigować ten kod działa!

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

Ale nie ograniczać pól tekstowych, ale inne

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

Aby zapobiec temu dla określonego pola wystarczy użyć

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

Nawiązując do tego poniżej!

Unikaj powrotu BACKSPACE z jQuery (jak Strona główna Google)

 7
Author: Syed Ehtsham Abbas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:37

Nie wiem, dlaczego nikt nie odpowiedział na to pytanie-wydaje się całkowicie rozsądne pytanie techniczne, aby zapytać, czy to możliwe.

Nie, Nie wydaje mi się, aby można było wyłączyć przycisk backspace w przeglądarce. Wiem, że nie jest domyślnie włączony w FF te dni choć.

 6
Author: brabster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-29 22:34:50

Łączenie rozwiązań podanych przez "thetoolman" & & "Biff MaGriff"

Poniższy kod wydaje się działać poprawnie w 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
Author: CodeNepal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 09:03:22

Większość odpowiedzi jest w jquery. Możesz to zrobić doskonale w czystym Javascript, prosty i nie wymaga biblioteki. Ten artykuł był dla mnie dobrym punktem wyjścia, ale ponieważ keyIdentifier jest przestarzały, chciałem, aby ten kod był bardziej bezpieczny, więc dodałem ||e.keyCode==8 do instrukcji if. Ponadto kod nie działał dobrze na Firefoksie, więc dodałem return false; i teraz działa doskonale. Tutaj jest:

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

Ten kod działa świetnie ponieważ,

  1. jest w czystym javascript (nie jest wymagana biblioteka).
  2. nie tylko sprawdza wciśnięty klawisz, ale także potwierdza, czy akcja jest naprawdę akcją "Wstecz" przeglądarki.
  3. wraz z powyższym, użytkownik może wpisywać i usuwać tekst z pól tekstowych wprowadzania na stronie internetowej bez żadnych problemów, jednocześnie uniemożliwiając działanie przycisku Wstecz.
  4. jest krótki, czysty, szybki i prosto do punktu.

Możesz dodać konsolę.log (e); dla Twojego testu cele i naciśnij F12 w chrome, przejdź do zakładki "console" i naciśnij "backspace" na stronie i zajrzyj do niej, aby zobaczyć, jakie wartości są zwracane, a następnie możesz skierować wszystkie te parametry, aby jeszcze bardziej ulepszyć powyższy kod, aby dostosować go do swoich potrzeb.

 4
Author: Tarik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-15 18:07:57

To rozwiązanie jest podobne do innych, które zostały opublikowane, ale używa prostej białej listy, dzięki czemu można je łatwo dostosować, aby zezwolić na backspace w określonych elementach, po prostu ustawiając selektor w funkcji.is ().

Używam go w tej formie, aby zapobiec cofaniu się backspace na stronach:

$(document).on("keydown", function (e) {
    if (e.which === 8 && !$(e.target).is("input:not([readonly]), textarea")) {
        e.preventDefault();
    }
});
 3
Author: J.Money,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-07 03:28:35

Aby nieco rozwinąć doskonałą odpowiedź @erikkallen , Oto funkcja, która pozwala na wszystkie typy wprowadzania oparte na klawiaturze, w tym te wprowadzone w 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
Author: Gingi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:29

JavaScript - jQuery way:

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

Javascript-natywny sposób, który działa dla mnie:

<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
Author: Vladimir Djuricic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-24 07:50:33

Trudno mi było znaleźć odpowiedź Nie-JQUERY. Dzięki Stasowi za umieszczenie mnie na torze.

Chrome: Jeśli nie potrzebujesz obsługi między przeglądarkami, możesz po prostu użyć czarnej listy, a nie białej listy. Ta czysta wersja JS działa w Chrome, ale nie w IE. Nie jestem pewien co do FF.

In Chrome (ver. 36, połowa 2014), naciśnięcia klawiszy nie na elemencie wejściowym lub contenteditable wydają się być ukierunkowane na <BODY>. Dzięki temu możliwe jest użycie czarnej listy, którą wolę na białej liście. IE używa celu ostatniego kliknięcia - więc może to być div lub cokolwiek innego. To czyni to bezużytecznym w 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();
        }
    }
}  

Cross Browser: dla czystego javascript, znalazłem odpowiedź Stasa za najlepszą. Dodanie jeszcze jednego warunku dla contenteditable sprawiło, że zadziałało dla mnie*:

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

*zauważ, że IEs [edit: i Spartan/TechPreview] mają "funkcję", która sprawia, że elementy związane z tabelą są nieedytowalne . Jeśli klikniesz jeden z nich, a następnie naciśniesz backspace, nastąpi powrót. Jeśli nie ma edytowalnych <td>s, to nie jest problem.

 3
Author: Josiah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-07 00:13:31

Miałem pewne problemy z przyjętym rozwiązaniem i Select2.js plugin; nie udało mi się usunąć znaków w edytowalnym polu, ponieważ blokowano akcję usuwania. To było moje rozwiązanie:

//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 tworzy zakres z atrybutem "contentEditable", który jest ustawiony na true dla edytowalnego pola combo w nim. Dodałem kod do konta tagname i inny atrybut. To rozwiązało wszystkie moje problemy.

Edit: jeśli nie używasz select2 combobox plugin dla jquery, to rozwiązanie może nie być potrzebne przez Ciebie, a przyjęte rozwiązanie może być lepsze.

 2
Author: Pytry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-06 15:56:08
    document.onkeydown = function (e) {    
        e.stopPropagation();
        if ((e.keyCode==8  ||  e.keyCode==13) &&
            (e.target.tagName != "TEXTAREA") && 
            (e.target.tagName != "INPUT")) { 
            return false;
        }
    };
 1
Author: elico3000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-14 21:59:16

Ten kod rozwiązuje problem we wszystkich przeglądarkach:

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
Author: Haseeb Akhtar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-23 14:45:04

Najprostszy sposób zapobiegania nawigacji po naciśnięciu backspace

$(document).keydown(function () {
    if (event.keyCode == 8) {
        if (event.target.nodeName == 'BODY') {
            event.preventDefault();
        }
    }
});
 1
Author: Mohammed Irfan Mayan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-17 14:12:22

Używając Dojo toolkit 1.7, działa to w 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
Author: Chris V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-26 12:17:24

Czy próbowałeś prostego rozwiązania polegającego na dodaniu następującego atrybutu do pola tekstowego tylko do odczytu:

Onkeydown= "return false;"

Spowoduje to, że przeglądarka nie powróci do historii po naciśnięciu klawisza Backspace w polu tekstowym tylko do odczytu. Może brakuje mi twoich prawdziwych intencji, ale wydaje mi się, że to byłoby najprostsze rozwiązanie twojego problemu.

 1
Author: B-Dog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-16 03:33:39

[[2]}znacznie lepsze rozwiązanie-

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

Na przemian, można sprawdzić tylko, czy

$(document.activeElement).is('body')
 1
Author: Robin Maben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-26 12:40:48

Czysta wersja javascript, która działa we wszystkich przeglądarkach:

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

Oczywiście możesz użyć "INPUT, TEXTAREA" i użyć " if (!regex.test (elements))". Pierwszy mi się udał.

 1
Author: Stanislav Parkhomenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-06 13:26:12

Wydajność?

Martwiłem się o występ i zrobiłem skrzypce: http://jsfiddle.net/felvhage/k2rT6/9/embedded/result/

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

Przeanalizowałem najbardziej obiecujące metody, jakie znalazłem w tym wątku. Okazuje się, że wszystkie były bardzo szybkie i najprawdopodobniej nie powodują problemu pod względem "ospałości" podczas pisania. Najwolniejszą metodą, na którą patrzyłem, było około 125 ms dla 10.000 połączeń w IE8. Czyli 0,0125 ms na udar.

Znalazłem metody wysłany przez Codenepal i Robin Maben być najszybszy ~ 0.001 ms (IE8) ale uważaj na różne semantyki.

Być może jest to ulga dla kogoś wprowadzającego tego rodzaju funkcjonalność do swojego kodu.

 1
Author: felvhage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-27 22:22:27

Zmodyfikowana odpowiedź erikkallen:

$(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
Author: Prozi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-25 08:22:11

To rozwiązanie działało bardzo dobrze podczas testów.

Dodałem trochę kodu do obsługi niektórych pól wejściowych nie oznaczonych danymi wejściowymi i do integracji w aplikacji Oracle PL / SQL, która generuje formularz wejściowy dla mojej pracy.

Moje "dwa grosze":

 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
Author: Luis Cuellar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 13:49:04

Stworzyłem projekt NPM z czystą wersją aktualnie akceptowanego (erikkallen)

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

Używa zasadniczo tych samych zasad, ale:

  • brak zależności
  • Wsparcie dla contenteditable
  • bardziej czytelna / utrzymywalna baza kodu
  • będzie obsługiwany, ponieważ będzie używany w produkcji przez moją firmę
  • Licencja 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
Author: Sebastien Lorber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-07 08:50:39

Oto moja przeróbka najczęściej głosowanej odpowiedzi. Próbowałem sprawdzić element.wartość!= = undefined (ponieważ niektóre elementy, takie jak może nie mieć atrybutu html, ale może mieć właściwość JavaScript value gdzieś w łańcuchu prototypów), jednak to nie działa zbyt dobrze i miał wiele przypadków krawędzi. Nie wydaje się, aby był to dobry sposób na przyszłość, więc biała lista wydaje się najlepszą opcją.

To rejestruje element na końcu fazy bąbelkowej zdarzenia, więc jeśli chcesz obsłużyć Backspace w dowolny niestandardowy sposób, możesz to zrobić w innych manipulatorach.

To również sprawdza instanceof HTMLTextAreElement, ponieważ teoretycznie można mieć komponent internetowy, który dziedziczy z tego.

To nie sprawdza contentEditable (połącz z innymi odpowiedziami).

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
Author: ninjagecko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-14 08:56:19

Sitepoint: Disable back for Javascript

event.stopPropagation() i event.preventDefault() nic nie robić w IE. Musiałem wysłać return event.keyCode == 11 (właśnie coś wybrałem) zamiast po prostu powiedzieć "if not = 8, run the event", aby to działało. event.returnValue = false również działa.

 0
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-18 23:10:39

Inna metoda wykorzystująca 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
Author: CodeNepal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-12 13:00:32

Używam tego w moim kodzie od jakiegoś czasu. Pisałem testy online dla uczniów i napotkałem problem, gdy uczniowie naciskali backspace podczas testu i to zabrało ich z powrotem do ekranu logowania. Frustrujące! Na pewno działa na FF.

document.onkeypress = Backspace;
function Backspace(event) {
    if (event.keyCode == 8) {
        if (document.activeElement.tagName == "INPUT") {
            return true;
        } else {
            return false;
        }
    }
}
 0
Author: Tan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-04 09:27:06