Как я могу предотвратить переход от обратного ключа обратно?

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

решает проблему, но делает ключ backspace непригодным для использования на странице, что даже хуже, чем исходное поведение.

EDIT: Причина, по которой я делаю это, заключается в том, что я не создаю простую веб-страницу, а большое приложение. Это невероятно раздражает потерять 10 минут работы только потому, что вы нажали обратно в неправильном месте. Соотношение предотвращения ошибок и раздражающих пользователей должно быть выше 1000/1, предотвращая возврат назад к предыдущему окну.

EDIT2: Я не, пытаясь предотвратить навигацию по истории, просто несчастные случаи.

EDIT3: комментарий @brentonstrines (перемещен здесь, так как вопрос настолько популярен): Это долгосрочное "исправление", но вы можете бросить свою поддержку за Ошибка Chromium, чтобы изменить это поведение в webkit

Ответ 1

Этот код решает проблему, по крайней мере, в 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;
        }
    }
});

Ответ 2

Этот код работает во всех браузерах и проглатывает ключ backspace, если не находится в элементе формы, или если элемент формы отключен | 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();
            }
        }
    });
});

Ответ 3

Другие ответы здесь доказали, что это невозможно сделать без элементов белого списка, в которых разрешен Backspace. Это решение не является идеальным, поскольку белый список не так прост, как просто текстовые поля и ввод текста/пароля, но часто оказывается неполным и нуждается в обновлении.

Однако, поскольку целью подавления функциональности backspace является просто предотвращение случайной потери данных пользователями, решение beforeunload является хорошим, потому что модальное всплывающее окно вызывает удивление - модальные всплывающие окна плохие, когда они запускаются как часть стандартного рабочего процесса, потому что пользователь привык отклонять их, не читая их, и они раздражают. В этом случае модальное всплывающее окно появляется только в качестве альтернативы редкому и неожиданному действию и поэтому является приемлемым.

Проблема заключается в том, что модал onbeforeunload не должен появляться, когда пользователь уходит со страницы (например, при нажатии на ссылку или при отправке формы), и мы не хотим создавать белый или черный список определенных условий onbeforeunload.

Идеальная комбинация компромиссов для обобщенного решения заключается в следующем: следите за тем, нажата ли клавиша Backspace, и открывайте только модальное состояние onbeforeunload, если оно есть. Другими словами:

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

Это было протестировано для работы в IE7+, FireFox, Chrome, Safari и Opera. Просто вставьте эту функцию в ваш global.js и вызывайте ее с любой страницы, где вы не хотите, чтобы пользователи случайно потеряли свои данные.

Обратите внимание, что модальный режим onbeforeunload может быть запущен только один раз, поэтому, если пользователь снова нажимает клавишу Backspace, модальный режим не будет запускаться снова.

Обратите внимание, что это не сработает при событиях hashchange, однако в этом контексте вы можете использовать другие методы, чтобы пользователи не могли случайно потерять свои данные.

Ответ 4

Более элегантное/сжатое решение:

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

Ответ 5

Модификация erikkallen Ответ на адрес различных типов ввода

Я обнаружил, что предприимчивый пользователь может нажать backspace на флажке или переключателе в тщетной попытке очистить его, и вместо этого они будут перемещаться назад и потерять все свои данные.

Это изменение должно решить эту проблему.

Новое Редактировать для адресата редактируемые 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();
    });

Пример
Для проверки сделайте 2 файла.

starthere.htm - откройте это первым, чтобы у вас было место, чтобы вернуться к

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

test.htm - Это будет перемещаться назад, когда будет нажата кнопка backspace, когда флажок или представление имеют фокус (достигнутый путем табуляции). Замените мой код на исправление.

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

Ответ 6

На основании комментариев, которые вы хотите, чтобы люди теряли информацию в формах, если они нажимают backspace для удаления, но поле не сфокусировано.

В этом случае вы хотите посмотреть обработчик события onunload. Qaru использует его - если вы попытаетесь покинуть страницу, когда вы начали писать ответ, появляется предупреждение.

Ответ 7

Прекратить работу с этим кодом!

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

Но не для ограничения текстовых полей, а для других

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

Чтобы предотвратить это для конкретного поля, просто используйте

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

Ссылаясь на это ниже!

Предотвратить перегрузку BACKSPACE с помощью jQuery (например, Домашняя страница Google)

Ответ 8

Большинство ответов в JQuery. Вы можете сделать это идеально в чистом Javascript, простом и не требующем библиотеки. Эта статья была хорошей отправной точкой для меня, но поскольку keyIdentifier устарел, я хотел, чтобы этот код был более безопасным, поэтому я добавил || e.keyCode == 8 в оператор if. Кроме того, код не работал на Firefox, поэтому я добавил return false; и теперь это работает на отлично Вот оно:

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

Этот код прекрасно работает, потому что,

  1. Это в чистом JavaScript (библиотека не требуется).
  2. Он не только проверяет нажатую клавишу, но и подтверждает, действительно ли это действие "назад" браузера.
  3. Вместе с вышеизложенным пользователь может без каких-либо проблем вводить и удалять текст из текстовых полей ввода на веб-странице, в то же время предотвращая действие кнопки "Назад".
  4. Это коротко, чисто, быстро и прямо к делу.

Вы можете добавить console.log(e); для ваших целей тестирования, и нажмите F12 в Chrome, перейдите на вкладку "консоль" и нажмите "Backspace" на странице и загляните внутрь, чтобы увидеть, какие значения возвращаются, затем вы можете настроить все эти параметры для дальнейшего улучшения кода выше, чтобы удовлетворить ваши потребности.

Ответ 9

Не уверен, почему никто не ответил на это - кажется совершенно разумным техническим вопросом, чтобы спросить, возможно ли это.

Нет, я не думаю, что есть кросс-браузерный способ отключить кнопку backspace. Я знаю, что это не включено по умолчанию в FF в наши дни.

Ответ 10

Сочетание решений, предоставляемых "thetoolman" && "Бифф Магриф"

следующий код работает корректно в 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();
    });
}); 

Ответ 11

Это решение похоже на другие, которые были опубликованы, но использует простой белый список, который легко настраивается, чтобы позволить backspace в указанных элементах просто устанавливая селектор в функции .is().

Я использую его в этой форме, чтобы предотвратить обратное перемещение страниц на страницах:

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

Ответ 12

Чтобы немного уточнить на @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();
    }
});

Ответ 13

Мне было трудно найти ответ на не-JQUERY. Спасибо Стасу за то, что он поставил меня на трассу.

Chrome: Если вам не нужна поддержка кросс-браузера, вы можете просто использовать черный список, а не белый список. Эта чистая версия JS работает в Chrome, но не в IE. Не уверен в FF.

В Chrome (версия 36, середина 2014 года) нажатие клавиш не на входном или контентном элементе кажется нацеленным на <BODY>. Это позволяет использовать черный список, который я предпочитаю "белый список". IE использует последнюю цель клика - так что это может быть div или что-то еще. Это делает это бесполезным в IE.

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

Cross Browser: Для чистого javascript я нашел ответ Стаса лучшим. Добавление еще одной проверки состояния для contenteditable заставил ее работать для меня *:

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 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: и Spartan/TechPreview] есть функция, которая делает элементы, связанные с таблицей, неотредактированными. Если вы нажмете на один из них, а THEN нажимаете кнопку backspace, он вернется назад. Если у вас нет редактируемого <td> s, это не проблема.

Ответ 14

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>

Ответ 15

У меня возникли проблемы с принятым решением и плагином 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 создает Span с атрибутом "contentEditable", для которого установлено значение true для редактируемого поля со списком. Я добавил код для учета тегов tagName и другого атрибута. Это решило все мои проблемы.

Изменить: если вы не используете плагин Select2 combobox для jquery, это решение вам может не понадобиться, и принятое решение может быть лучше.

Ответ 16

Этот код решает проблему во всех браузерах:

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

  }

Ответ 17

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

Ответ 18

Простейший способ предотвращения навигации при нажатии backspace

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

Ответ 19

Используя 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()});
});

Ответ 20

Вы пробовали очень простое решение просто добавить следующий атрибут в текстовое поле только для чтения:

onkeydown = "return false;"

Это приведет к тому, что браузер не вернется в историю при нажатии клавиши Backspace в текстовом поле только для чтения. Возможно, мне не хватает вашего истинного намерения, но похоже, что это было бы самым простым решением вашей проблемы.

Ответ 21

Более эффективное решение -

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

Ответ 22

Чистая версия 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))". Первая работала отлично для меня.

Ответ 23

Производительность

Я беспокоился о производительности и сделал скрипку: http://jsfiddle.net/felvhage/k2rT6/9/embedded/result/

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

Я проанализировал наиболее перспективные методы, которые я нашел в этой теме. Оказывается, все они были очень быстрыми и, скорее всего, не вызывали проблемы с точки зрения "медлительности" при наборе текста. Самый медленный метод, на который я смотрел, составлял около 125 мс для 10.000 вызовов в IE8. Который составляет 0.0125мс за ход.

Я нашел методы, опубликованные Codenepal и Robin Maben, максимально быстрыми - 0.001ms (IE8), но остерегайтесь различной семантики.

Возможно, это облегчение для кого-то, вводящего такую ​​функциональность в свой код.

Ответ 24

Измененный ответ 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;
    }
});

Ответ 25

Это решение очень хорошо работало при тестировании.

Я добавил код для обработки некоторых полей ввода, не помеченных вводом, и для интеграции в приложение Oracle PL/SQL, которое генерирует форму ввода для моей работы.

Мои "два цента":

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

Ответ 26

Я создал проект NPM с чистой версией принятого в настоящее время (от erikkallen)

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

Ответ 27

Вот моя переиздание ответа сверху. Я попытался проверить element.value! == undefined (поскольку некоторые элементы, например, могут не иметь атрибута html, но могут иметь свойство значения javascript где-то в цепочке прототипов), однако это не очень хорошо работает и имеет много преимуществ случаев. Кажется, что это не лучший способ обеспечить будущее, поэтому лучший вариант - белый список.

Это регистрирует элемент в конце фазы пузырьков событий, поэтому, если вы хотите обрабатывать Backspace любым настраиваемым способом, вы можете сделать это в других обработчиках.

Это также проверяет экземпляр HTMLTextAreElement, поскольку теоретически может существовать веб-компонент, который наследует от него.

Это не проверяет 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

Ответ 28

Другой метод, использующий 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>

Ответ 29

Sitepoint: Отключить обратно для Javascript

event.stopPropagation() и event.preventDefault() ничего не делают в IE. Мне пришлось отправить return event.keyCode == 11 (я только что выбрал что-то) вместо того, чтобы просто сказать "if not = 8, run the event", чтобы он работал. event.returnValue = false также работает.

Ответ 30

Я использовал это в своем коде уже некоторое время. Я пишу онлайн-тесты для студентов и сталкивался с проблемой, когда ученики нажимали backspace во время их теста, и они вернули их на экран входа в систему. Срыв! Он работает на FF наверняка.

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