¿Cómo puedo evitar que la tecla retroceso navegue hacia atrás?


En IE puedo hacer esto con el (terriblemente no estándar, pero trabajando) jQuery

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

Pero ¿es posible hacerlo de una manera que funcione en Firefox, o de una manera cruzada de navegador para un bono?

Para que conste:

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

No hace nada.

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

Resuelve el problema, pero hace que la tecla de retroceso sea inutilizable en la página, lo que es incluso peor que el comportamiento original.

EDITAR: La razón por la que hago esto es que no estoy creando una página web simple, sino una gran aplicación. Es increíblemente molesto perder 10 minutos de trabajo solo porque presionaste retroceso en el lugar equivocado. La relación de prevención de errores vs. usuarios molestos debe estar muy por encima de 1000/1 al evitar que la tecla retroceso navegue hacia atrás.

EDIT2: Estoy no tratando de evitar la navegación histórica, solo accidentes.

EDIT3: @brentonstrines comentario (movido aquí ya que la pregunta es tan popular): Esta es una 'solución' a largo plazo, pero podrías lanzar tu apoyo detrás del error de Chromium para cambiar este comportamiento en webkit

Author: John Weisz, 2009-09-30

30 answers

Este código resuelve el problema, al menos en IE y Firefox (no he probado ningún otro, pero le doy una oportunidad razonable de funcionar si el problema incluso existe en otros navegadores).

// 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-07 08:01:11

Este código funciona en todos los navegadores y se traga la tecla backspace cuando no está en un elemento de formulario, o si el elemento de formulario está deshabilitado|readOnly. También es eficiente, lo cual es importante cuando se ejecuta en cada tecla escrita.

$(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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-21 20:49:46

Las otras respuestas aquí han establecido que esto no se puede hacer sin elementos de lista blanca en los que se permite el retroceso. Esta solución no es ideal porque la lista blanca no es tan sencilla como las meras áreas de texto y las entradas de texto/contraseña, pero se encuentra repetidamente incompleta y necesita ser actualizada.

Sin embargo, dado que el propósito de suprimir la funcionalidad de retroceso es simplemente evitar que los usuarios pierdan datos accidentalmente, la solución beforeunload es una buena una porque la ventana emergente modal es sorprendente pop las ventanas emergentes modales son malas cuando se activan como parte de un flujo de trabajo estándar, porque el usuario se acostumbra a descartarlas sin leerlas, y son molestas. En este caso, la ventana emergente modal solo aparecería como una alternativa a una acción rara y sorprendente, y por lo tanto es aceptable.

El problema es que un modal onbeforeunload no debe aparecer cada vez que el usuario navega fuera de la página (como al hacer clic en un enlace o enviar un formulario), y no queremos comenzar a incluir en la lista blanca o en la lista negra condiciones específicas de onbeforeunload.

La combinación ideal de compensaciones para una solución generalizada es la siguiente: mantenga un registro de si se presiona backspace, y solo abra el modal onbeforeunload si lo está. En otras palabras:

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

Esto ha sido probado para funcionar en IE7+, FireFox, Chrome, Safari y Opera. Simplemente deje caer esta función en su global.js y llámalo desde cualquier página donde no quieras los usuarios pierden accidentalmente sus datos.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-10 17:44:51

Una solución más elegante/concisa:

$(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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-25 12:17:13

Modificación de la respuesta de erikkallen para abordar diferentes tipos de entrada

He encontrado que un usuario emprendedor podría presionar retroceso en una casilla de verificación o un botón de opción en un intento vano de borrarlo y en su lugar navegaría hacia atrás y perdería todos sus datos.

Este cambio debería abordar esa cuestión.

Nueva edición para abordar divs editables de contenido

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

Ejemplo
Para probar hacer 2 archivos.

Comienza aquí.htm - abre esto primero para que tengas un lugar al que volver

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

Prueba.htm-Esto navegará hacia atrás cuando se presione el espacio atrás mientras la casilla de verificación o enviar tiene foco (logrado mediante pestañas). Reemplazar con mi código para arreglar.

<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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-23 23:01:04

Basado en los comentarios, parece que desea evitar que las personas pierdan información en los formularios, si presionan retroceso para eliminar, pero el campo no está enfocado.

En cuyo caso, desea mirar el controlador de eventos onunload. Stack Overflow lo usa: si intentas abandonar una página cuando empiezas a escribir una respuesta, aparece una advertencia.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-29 23:23:39

¡Dejar de navegar por este código funciona!

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

Pero para no restringir los campos de texto sino otros

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

Para prevenirlo para un campo específico simplemente use

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

En referencia a este a continuación!

Evitar que BACKSPACE navegue hacia atrás con jQuery (Como la página de inicio de 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:37

No estoy seguro de por qué nadie acaba de responder esto, parece una pregunta técnica perfectamente razonable para preguntar si es posible.

No, no creo que haya una forma cruzada navegador para desactivar el botón de retroceso. Sé que no está habilitado por defecto en FF en estos días, sin embargo.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-29 22:34:50

Combinando soluciones dadas por" thetoolman " & & "Biff MaGriff"

El siguiente código parece funcionar correctamente en 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 09:03:22

La mayoría de las respuestas están en jquery. Puede hacer esto perfectamente en Javascript puro, simple y sin necesidad de biblioteca. Este artículo fue un buen punto de partida para mí, pero como KeyIdentifier está obsoleto, quería que este código fuera más seguro, así que agregué ||e.keyCode==8 a la instrucción if. Además, el código no funcionaba bien en Firefox, así que agregué return false; y ahora funciona perfectamente bien. Aquí está:

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

Este código funciona muy bien porque,

  1. Está en javascript puro (no se requiere biblioteca).
  2. No solo comprueba la tecla presionada, sino que confirma si la acción es realmente una acción de "retroceso" del navegador.
  3. Junto con lo anterior, el usuario puede escribir y eliminar texto de los cuadros de texto de entrada en la página web sin ningún problema, al tiempo que evita la acción del botón atrás.
  4. Es corto, limpio, rápido y directo al grano.

Puede agregar consola.registro (e); para su su prueba propósitos, y pulse F12 en chrome, vaya a la pestaña" consola "y pulse" retroceso " en la página y mirar dentro de ella para ver qué valores se devuelven, a continuación, puede dirigirse a todos esos parámetros para mejorar aún más el código anterior para satisfacer sus necesidades.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-15 18:07:57

Esta solución es similar a otras que se han publicado, pero utiliza una simple lista blanca que lo hace fácilmente personalizable para permitir el retroceso en elementos especificados simplemente configurando el selector en la función .is ().

Lo uso en esta forma para evitar que el retroceso en las páginas navegue hacia atrás:

$(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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-07 03:28:35

Para profundizar un poco en la excelente respuesta de @ erikkallen , aquí hay una función que permite todos los tipos de entrada basados en el teclado, incluidos los introducidos en 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
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 - la forma nativa, que funciona para mí:

<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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-24 07:50:33

Me costó encontrar una respuesta que no fuera de JQUERY. Gracias a Stas por ponerme en la pista.

Chrome: Si no necesitas compatibilidad con otros navegadores, puedes usar una lista negra en lugar de una lista blanca. Esta versión JS pura funciona en Chrome, pero no en IE. No estoy seguro sobre FF.

En Chrome (ver. 36, mediados de 2014), las pulsaciones de teclas no en un elemento input o contenteditable parecen estar dirigidas a <BODY>. Esto hace posible el uso de una lista negra, que prefiero a la lista blanca. IE utiliza el destino del último clic, por lo que podría ser un div o cualquier otra cosa. Eso hace que esto sea inútil en 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: Para javascript puro, encontré que la respuesta de Stas es la mejor. Agregar una comprobación de condición más para contenteditable hizo que funcionara para mí*:

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

*Tenga en cuenta que IEs [editar: y Spartan/TechPreview] tienen una "característica" que hace que los elementos relacionados con la tabla no sean editables. Si hace clic en uno de ellos y luego presiona retroceso, navegará hacia atrás. Si no tiene <td>s editables, esto no es un problema.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-07 00:13:31

Tuve algunos problemas con la solución aceptada y el Select2.plugin js; No pude eliminar caracteres en el cuadro editable ya que se estaba impidiendo la acción de eliminación. Esta fue mi solución:

//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 crea un Span con un atributo de "contentEditable" que se establece en true para el cuadro combinado editable en él. He añadido código para dar cuenta de los spans tagName y el atributo diferente. Esto resolvió todos mis problemas.

Editar: Si no está utilizando el Select2 combobox plugin para jquery, entonces esta solución puede no ser necesaria por usted, y la solución aceptada podría ser mejor.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-14 21:59:16

Este código resuelve el problema en todos los navegadores:

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-23 14:45:04

La forma más sencilla de evitar la navegación al presionar retroceso

$(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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-17 14:12:22

Usando Dojo toolkit 1.7, esto funciona en 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-26 12:17:24

¿Ha intentado la solución muy simple de simplemente agregar el siguiente atributo a su campo de texto de solo lectura:

Onkeydown = "return false;"

Esto evitará que el navegador retroceda en el historial cuando se presione la tecla Retroceso en un campo de texto de solo lectura. Tal vez me estoy perdiendo su verdadera intención, pero parece que esta sería la solución más simple a su problema.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-16 03:33:39

Una solución mucho más limpia -

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

Alternativamente, solo se puede comprobar si

$(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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-26 12:40:48

Versión javascript pura, que funciona en todos los navegadores:

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

Por supuesto, puede usar "INPUT, TEXTAREA" y usar " if (!regex.prueba (elementos)) " entonces. El primero funcionó bien para mí.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-06 13:26:12

¿Actuación?

Estaba preocupado por la actuación e hice un violín: http://jsfiddle.net/felvhage/k2rT6/9/embedded/result /

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

He analizado los métodos más prometedores que encontré en este hilo. Resulta que todos eran muy rápidos y lo más probable es que no causen un problema en términos de "lentitud" al escribir. El método más lento que miré fue de aproximadamente 125 ms para 10.000 llamadas en IE8. Que es 0.0125 ms por carrera.

Encontré los métodos publicado por Codenepal y Robin Maben para ser más rápido ~ 0.001 ms (IE8), pero tenga cuidado con las diferentes semánticas.

Tal vez esto sea un alivio para alguien que introduce este tipo de funcionalidad en su código.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-27 22:22:27

Respuesta modificada de 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-25 08:22:11

Esta solución funcionó muy bien cuando se probó.

Añadí algún código para manejar algunos campos de entrada no etiquetados con input, y para integrarlos en una aplicación Oracle PL/SQL que genera un formulario de entrada para mi trabajo.

Mis "dos centavos":

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-28 13:49:04

He creado un proyecto NPM con una versión limpia de la actualmente aceptada (de erikkallen)

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

Utiliza básicamente los mismos principios pero:

  • Sin dependencia
  • Soporte para contenteditable
  • Código base más legible / mantenible
  • Será compatible ya que será utilizado en producción por mi empresa
  • Licencia 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-07 08:50:39

Aquí está mi reescritura de la respuesta más votada. Traté de comprobar Element.valor!= = indefinido (ya que algunos elementos como pueden no tener ningún atributo html pero pueden tener una propiedad de valor javascript en algún lugar de la cadena de prototipos), sin embargo, eso no funcionó muy bien y tenía muchos casos de borde. No parece haber una buena manera de prepararlo para el futuro, por lo que una lista blanca parece la mejor opción.

Esto registra el elemento al final de la fase de burbuja de evento, por lo que si desea manejar el retroceso en de cualquier forma personalizada, puede hacerlo en otros manejadores.

Esto también comprueba la instancia de HTMLTextAreElement ya que teóricamente uno podría tener un componente web que hereda de eso.

Esto no comprueba contentEditable (combine con otras respuestas).

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-14 08:56:19

Sitepoint: Desactivar de nuevo para Javascript

event.stopPropagation() y event.preventDefault() no hacer nada en IE. Tuve que enviar return event.keyCode == 11 (acabo de elegir algo) en lugar de solo decir "if not = 8, run the event" para que funcione, sin embargo. event.returnValue = false también funciona.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-18 23:10:39

Otro método usando 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-12 13:00:32

He estado usando esto en mi código desde hace algún tiempo. Escribo pruebas en línea para los estudiantes y me encontré con el problema cuando los estudiantes estaban presionando retroceso durante su prueba y los llevaría de vuelta a la pantalla de inicio de sesión. Frustrante! Funciona en FF con seguridad.

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-04 09:27:06