¿El mejor método entre navegadores para capturar CTRL + S con JQuery?

162

A mis usuarios les gustaría poder presionar Ctrl+ Spara guardar un formulario. ¿Existe una buena manera de capturar la combinación de teclas Ctrl+ entre navegadores Sy enviar mi formulario?

La aplicación está construida en Drupal, por lo que jQuery está disponible.

ceejayoz
fuente

Respuestas:

121
$(window).keypress(function(event) {
    if (!(event.which == 115 && event.ctrlKey) && !(event.which == 19)) return true;
    alert("Ctrl-S pressed");
    event.preventDefault();
    return false;
});

Los códigos clave pueden diferir entre los navegadores, por lo que es posible que deba verificar más de 115.

Jim
fuente
55
en los navegadores webkit de OS X, cmd + s devuelve 19, por lo que también vale la pena comprobarlo. es decir, si (! (event.which == 115 && event.ctrlKey) &&! (event.which == 19)) devuelve verdadero;
Tadas T
66
Solo funciona en Firefox para mí. IE9 y Chrome no registran ninguna pulsación de tecla.
Pelms
77
Incluso con $ (document) .keypress (en lugar de $ (window) .keypress), IE y Chrome aún toman el evento de pulsación de tecla con 'Ctrl' antes de que lo haga el script.
pelms
16
usar en keydownlugar de keypressen cromo
destan
3
Desafortunadamente está desactualizado
Cannicide
250

Esto funciona para mí (usando jquery) para sobrecargar Ctrl+ S, Ctrl+ Fy Ctrl+ G:

$(window).bind('keydown', function(event) {
    if (event.ctrlKey || event.metaKey) {
        switch (String.fromCharCode(event.which).toLowerCase()) {
        case 's':
            event.preventDefault();
            alert('ctrl-s');
            break;
        case 'f':
            event.preventDefault();
            alert('ctrl-f');
            break;
        case 'g':
            event.preventDefault();
            alert('ctrl-g');
            break;
        }
    }
});
Danny Ruijters
fuente
8
Esta es la única respuesta que funcionó para mí en todos los navegadores que probé, incluida Chrome Versión 28.0.1500.71
T. Brian Jones
27
Se puede hacer con JS puro si se usa en window.addEventListener(lugar de$(window).bind(
2
@NatesS si elimina la alerta, no abre el cuadro de diálogo Guardar. Es causado por alerta. Funciona bien para mí en todos los navegadores. Buena solución.
CrazyNooB
2
Trabajó para mi. Por favor, acepte esta respuesta que la anterior.
pavanw3b
1
@Fireflight: un else ifno funcionará porque la ifdeclaración original ya se evaluará como verdadera. Tendrá que poner su código antes de la ifdeclaración original , convirtiendo el original en un else if.
Danny Ruijters
29

Esta solución jQuery funciona para mí en Chrome y Firefox, tanto para Ctrl+ Scomo Cmd+ S.

$(document).keydown(function(e) {

    var key = undefined;
    var possible = [ e.key, e.keyIdentifier, e.keyCode, e.which ];

    while (key === undefined && possible.length > 0)
    {
        key = possible.pop();
    }

    if (key && (key == '115' || key == '83' ) && (e.ctrlKey || e.metaKey) && !(e.altKey))
    {
        e.preventDefault();
        alert("Ctrl-s pressed");
        return false;
    }
    return true;
}); 
Alan Bellows
fuente
1
Esta es la única solución que funciona correctamente aquí. ¡Muchas gracias!
Stephan Weinhold
1
esto podría estar desactualizado ahora: use en e.keylugar de e.which;
Cannicidio
Actualizado el 14 de mayo de 2017 para los estándares modernos.
Alan Bellows
28

Este funcionó para mí en Chrome ... por alguna razón me event.whichdevuelve una S mayúscula (83), no estoy seguro de por qué (independientemente del estado de bloqueo de mayúsculas), así que solía fromCharCodey toLowerCasesolo para estar seguro

$(document).keydown(function(event) {

    //19 for Mac Command+S
    if (!( String.fromCharCode(event.which).toLowerCase() == 's' && event.ctrlKey) && !(event.which == 19)) return true;

    alert("Ctrl-s pressed");

    event.preventDefault();
    return false;
});

Si alguien sabe por qué tengo 83 y no 115 , me alegrará saberlo, también si alguien prueba esto en otros navegadores, me alegrará saber si funciona o no.

Eran Medan
fuente
Tengo este mismo problema con Chrome. ¡Que problematico!
qodeninja el
PD: ahora que lo miro, creo que preventDefault es redundante ya que return false lo dispara (y stopPropagation) pero no estoy seguro de que sea muy importante para la pregunta
Eran Medan
7

Combiné algunas opciones para admitir FireFox, IE y Chrome. También lo actualicé para admitir mejor mac

// simply disables save event for chrome
$(window).keypress(function (event) {
    if (!(event.which == 115 && (navigator.platform.match("Mac") ? event.metaKey : event.ctrlKey)) && !(event.which == 19)) return true;
    event.preventDefault();
    return false;
});

// used to process the cmd+s and ctrl+s events
$(document).keydown(function (event) {
     if (event.which == 83 && (navigator.platform.match("Mac") ? event.metaKey : event.ctrlKey)) {
        event.preventDefault();
        save(event);
        return false;
     }
});
uadrive
fuente
5

Sinceramente, me gustaría que las aplicaciones web no anulen mis teclas de acceso directo predeterminadas. Ctrl+ Sya hace algo en los navegadores. Tener ese cambio abruptamente dependiendo del sitio que estoy viendo es disruptivo y frustrante, sin mencionar que a menudo tiene errores. He tenido sitios secuestrados Ctrl+ Tabporque se veía igual que Ctrl+ I, arruinando mi trabajo en el sitio y evitando que cambie de pestañas como de costumbre.

Si desea teclas de acceso directo, use el accesskeyatributo No rompa la funcionalidad existente del navegador.

Eevee
fuente
2
Estoy totalmente de acuerdo, pero desafortunadamente soy la persona que implementa, no la que toma las decisiones.
ceejayoz
24
Es cierto, pero CTRL + S no es una característica de uso frecuente. Dudo que la gente se lo pierda, especialmente si significa que puede guardar su archivo en su aplicación web.
EndangeredMassa
13
Yo normalmente de acuerdo con usted, pero la única vez que nunca CTRL-s en un navegador es cuando me olvido de que estoy usando una aplicación web y espero el acceso directo para hacer algo útil. Normalmente estoy decepcionado. Gmail guarda tu correo electrónico cuando presionas ctrl-s, aunque nunca lo notarías porque cuando solo hace lo que esperas, y lo que hace cada aplicación de escritorio, realmente no lo notas. USTED nota cuando cree que desea guardar Gmail como HTML, y es molesto.
Carson Myers
44
Esto realmente depende de la aplicación. Estoy creando una aplicación web de emulador de terminal y anular ctrl + c parece práctico si no es necesario.
Brack
La necesidad de guardar realmente una página HTML es bastante escasa, me encuentro haciendo esto nunca. Sin embargo, como han dicho otros, el navegador se está convirtiendo rápidamente en el lugar donde trabajamos, todo nuestro trabajo, y cada vez más navegadores están reemplazando a los procesadores de texto y otras aplicaciones que se usan tradicionalmente en el escritorio, los usuarios están acostumbrados a su teclado atajos, por lo que apoyarlos es imprescindible para la usabilidad y la adopción. Si creas un procesador de textos y me haces presionar ALT + MAYÚS + S o algo peor, voy a volcar tu aplicación como un mal hábito como usuario.
DavidScherer
4

@Eevee: a medida que el navegador se convierte en el hogar para una funcionalidad cada vez más rica y comienza a reemplazar las aplicaciones de escritorio, simplemente no será una opción para renunciar al uso de atajos de teclado. El rico e intuitivo conjunto de comandos de teclado de Gmail fue instrumental en mi disposición a abandonar Outlook. Los atajos de teclado en Todoist, Google Reader y Google Calendar hacen que mi vida sea mucho, mucho más fácil a diario.

Los desarrolladores definitivamente deben tener cuidado de no anular las pulsaciones de teclas que ya tienen un significado en el navegador. Por ejemplo, el cuadro de texto WMD en el que estoy escribiendo interpreta inexplicablemente Ctrl+ Delcomo "Blockquote" en lugar de "eliminar palabra hacia adelante". Tengo curiosidad por saber si hay una lista estándar en algún lugar de accesos directos "seguros para el navegador" que los desarrolladores del sitio puedan usar y que los navegadores se comprometan a mantenerse alejados en futuras versiones.

Hierba caudill
fuente
1
La respuesta es No, no hay una lista segura de accesos directos seguros para el navegador. Y es bueno para dos motivos: 1. Los accesos directos son personalizables (al menos en Opera). 2. Al hacerlo, no restringe la creatividad del proveedor del navegador para darle más poder para el uso del navegador en sí.
gizmo
3

$(document).keydown(function(e) {
    if ((e.key == 's' || e.key == 'S' ) && (e.ctrlKey || e.metaKey))
    {
        e.preventDefault();
        alert("Ctrl-s pressed");
        return false;
    }
    return true;
}); 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Try pressing ctrl+s somewhere.

Esta es una versión actualizada de la respuesta de @ AlanBellows, reemplazada whichpor key. También funciona incluso con la falla de la tecla mayúscula de Chrome (donde si presiona Ctrl+ Senvía S mayúscula en lugar de s). Funciona en todos los navegadores modernos.

Canicidio
fuente
Para probar esto, haga clic dentro del cuadro de fragmentos y presione Ctrl + S.
Cannicidio
1

Esta fue mi solución, que es mucho más fácil de leer que otras sugerencias aquí, puede incluir fácilmente otras combinaciones de teclas y se ha probado en IE, Chrome y Firefox:

$(window).keydown(function(evt) {
    var key = String.fromCharCode(evt.keyCode);
    //ctrl+s
    if (key.toLowerCase() === "s" && evt.ctrlKey) {
        fnToRun();
        evt.preventDefault(true);
        return false;
    }
    return true;
});
R. Salisbury
fuente
1
+1 por el uso de String.fromCharCode. Aunque, las Mac no tienen una clave de control. Pruebe la tecla de comando con evt.metaKey. Vuelve truepara Cmd en Mac y Win en Windows.
KatoFett
0

Esto debería funcionar (adaptado de https://stackoverflow.com/a/8285722/388902 ).

var ctrl_down = false;
var ctrl_key = 17;
var s_key = 83;

$(document).keydown(function(e) {
    if (e.keyCode == ctrl_key) ctrl_down = true;
}).keyup(function(e) {
    if (e.keyCode == ctrl_key) ctrl_down = false;
});

$(document).keydown(function(e) {
    if (ctrl_down && (e.keyCode == s_key)) {
        alert('Ctrl-s pressed');
        // Your code
        return false;
    }
}); 
pelmas
fuente
0

Para la respuesta de Alan Bellows:! (E.altKey) agregado para usuarios que usan AltGral escribir (por ejemplo, Polonia). Sin esta presión, AltGr+ Sdará el mismo resultado que Ctrl+S

$(document).keydown(function(e) {
if ((e.which == '115' || e.which == '83' ) && (e.ctrlKey || e.metaKey) && !(e.altKey))
{
    e.preventDefault();
    alert("Ctrl-s pressed");
    return false;
}
return true; });
Jaś Fasola
fuente
0

Este complemento hecho por mí puede ser útil.

Enchufar

Puede usar este complemento, debe proporcionar los códigos clave y la función para ejecutarse de esta manera

simulatorControl([17,83], function(){
 console.log('You have pressed Ctrl+Z');
});

En el código he mostrado cómo realizar para Ctrl+ S. Obtendrá documentación detallada en el enlace. El complemento está en la sección de código JavaScript de mi lápiz en Codepen.

10011101111
fuente
0

Resolví mi problema en IE , usando un alert("With a message")para evitar el comportamiento predeterminado:

window.addEventListener("keydown", function (e) {
    if(e.ctrlKey || e.metaKey){
        e.preventDefault(); //Good browsers
        if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) { //hack for ie
            alert("Please, use the print button located on the top bar");
            return;
        }
    }
});
usuario2570311
fuente