Лучший кросс-браузерный метод для захвата CTRL + S с JQuery?

162

Мои пользователи хотели бы иметь возможность нажать Ctrl+, Sчтобы сохранить форму. Есть ли хороший кросс-браузерный способ захвата комбинации клавиш Ctrl+ Sи отправки моей формы?

Приложение построено на Drupal, поэтому jQuery доступен.

ceejayoz
источник

Ответы:

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

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

Джим
источник
5
в браузерах OS X webkit cmd + s возвращает 19, так что это также стоит проверить. т.е. если (! (event.which == 115 && event.ctrlKey) &&! (event.which == 19)) вернуть true;
Tadas T
6
У меня работает только в Firefox. IE9 и Chrome не регистрируют нажатие клавиш.
Пелмс
7
Даже с $ (document) .keypress (вместо $ (window) .keypress) IE и Chrome по-прежнему фиксируют событие нажатия клавиши Ctrl до того, как это сделает скрипт.
pelms
16
использовать keydownвместо keypressхрома
дестан
3
К сожалению, это устарело
Cannicide
250

Это работает для меня (используя jquery) для перегрузки Ctrl+ S, Ctrl+ Fи 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;
        }
    }
});
Дэнни Руйтерс
источник
8
Это единственный ответ, который работал для меня во всех протестированных мной браузерах, включая Chrome версии 28.0.1500.71
Т. Брайан Джонс,
27
Выполняется с чистым JS, если вы используете window.addEventListener(вместо$(window).bind(
2
@NatesS, если вы удалите предупреждение, оно не откроет диалоговое окно сохранения. Это вызвано из-за тревоги. У меня отлично работает во всех браузерах. Хороший обходной путь.
CrazyNooB
2
Работал на меня. Пожалуйста, примите этот ответ, чем приведенный выше.
pavanw3b
1
@Fireflight: an else ifне будет работать, поскольку исходное ifутверждение уже будет оценено как истинное. Вы должны будете поместить свой код перед исходным ifоператором, превратив оригинал в else if.
Дэнни Руйтерс
34

Вы можете использовать библиотеку ярлыков для обработки специфических для браузера вещей.

shortcut.add("Ctrl+S",function() {
    alert("Hi there!");
});
EndangeredMassa
источник
7
Он был преобразован в плагин jQuery, разветвлен и разветвлен и теперь поддерживает 1.6.x: github.com/ricardovaleriano/jquery.hotkeys
Félix Saparelli,
12
Для других пользователей Google обновленный URL-адрес для плагина jQuery: github.com/jeresig/jquery.hotkeys
bgs264,
29

Это решение jQuery работает для меня в Chrome и Firefox для Ctrl+ Sи 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;
}); 
Алан Беллоуз
источник
1
Это единственное решение, которое работает здесь правильно. Большое спасибо!
Стефан Вайнхолд,
1
сейчас это может быть устаревшим: используйте e.keyвместо e.which;
Cannicide
Обновлено 14 мая 2017 года по современным стандартам.
Алан Беллоуз
28

Этот работал для меня на Chrome ... по какой-то причине event.whichвозвращает заглавную S (83) для меня, не уверен почему (независимо от состояния блокировки шапки), поэтому я использовал fromCharCodeи toLowerCaseпросто чтобы быть в безопасности

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

Если кто-то знает, почему я получаю 83, а не 115 , я буду рад услышать, а также, если кто-нибудь протестирует это в других браузерах, я буду рад услышать, работает ли он или нет

Эран Медан
источник
У меня такая же проблема с хромом. Такая боль!
qodeninja
ps теперь, когда я смотрю на него, я думаю, что protectDefault является избыточным, так как return false вызывает его (и stopPropagation), но не уверен, что это имеет большое значение для вопроса
Eran Medan
7

Я объединил несколько вариантов поддержки FireFox, IE и Chrome. Я также обновил его, чтобы лучше поддерживать 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
источник
5

Честно говоря, я бы хотел, чтобы веб-приложения не переопределяли мои стандартные сочетания клавиш. Ctrl+ Sуже что-то делает в браузерах. Это внезапное изменение в зависимости от сайта, который я просматриваю, разрушительно и разочаровывает, не говоря уже о том, что оно часто глючит. У меня был угон сайтов Ctrl+, Tabпотому что он выглядел так же, как Ctrl+ I, что разрушало мою работу на сайте и мешало мне переключать вкладки как обычно.

Если вы хотите сочетания клавиш, используйте accesskeyатрибут. Пожалуйста, не нарушайте существующие функции браузера.

Eevee
источник
2
Я полностью согласен, но, к сожалению, я являюсь ответственным за реализацию, а не принимаю решения.
Ceejayoz
24
Да, но CTRL + S - не часто используемая функция. Я сомневаюсь, что люди пропустят это, особенно если это означает, что вы можете сохранить свой файл в своем веб-приложении.
EndangeredMassa
13
Обычно я с вами согласен, но единственный раз, когда я использую ctrl-s в браузере, это когда я забываю, что использую веб-приложение, и ожидаю, что ярлык сделает что-то полезное. Я обычно разочарован. Gmail сохраняет вашу электронную почту, когда вы нажимаете ctrl-s, хотя вы никогда не заметите, потому что, когда она просто делает то, что вы ожидаете, и то, что делает каждое настольное приложение, вы не замечаете этого. Вы ДЕЙСТВИТЕЛЬНО замечаете, когда вам кажется, что вы хотите сохранить gmail как HTML, и это раздражает.
Карсон Майерс
4
Это действительно зависит от приложения. Я создаю веб-приложение эмулятора терминала и переопределение Ctrl + C кажется практичным, если не нужно.
Брек
Потребность в сохранении HTML-страницы довольно мала, я обнаружил, что делаю это никогда. Однако, как говорили другие, браузер быстро становится тем местом, где мы работаем, всю нашу работу, и все больше браузеров заменяют текстовые процессоры и другие приложения, традиционно используемые на рабочем столе, пользователи привыкли к их клавиатуре. ярлыки, поэтому поддержка их является обязательным условием для удобства использования и принятия. Если вы создадите текстовый процессор и заставите меня нажать ALT + SHIFT + S или что-то еще хуже, я собираюсь выбросить ваше приложение, как дурную привычку, как пользователя.
DavidScherer
4

@Eevee: Поскольку браузер становится домом для все более и более функциональных функций и начинает заменять настольные приложения, он просто не будет возможностью отказаться от использования сочетаний клавиш. Богатый и интуитивно понятный набор клавиатурных команд Gmail способствовал моей готовности отказаться от Outlook. Сочетания клавиш в Todoist, Google Reader и Google Calendar - все это делает мою жизнь намного проще в повседневной жизни.

Разработчики должны определенно быть осторожными, чтобы не отменять нажатия клавиш, которые уже имеют значение в браузере. Например, текстовое поле для оружия массового поражения, которое я печатаю необъяснимым образом, интерпретирует Ctrl+ Delкак «Blockquote», а не «удалить слово вперед». Мне любопытно, есть ли где-нибудь стандартный список «безопасных для браузера» ярлыков, которые разработчики сайтов могут использовать, и которые браузеры обязуются избегать в будущих версиях.

Херб Каудилл
источник
1
Ответ: нет, безопасного списка безопасных ярлыков браузера не существует. И это хорошо для двух причин: 1. Ярлыки настраиваются (по крайней мере, в Opera). 2. Таким образом, вы не ограничиваете творческие способности производителя браузера, чтобы дать вам больше возможностей для использования самого браузера.
штуковина
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.

Это актуальная версия ответа @ AlanBellows с заменой whichна key. Он также работает даже при сбое в работе с заглавной клавишей Chrome (если вы нажмете Ctrl+, Sвместо s будет отправлено заглавное S). Работает во всех современных браузерах.

Cannicide
источник
Чтобы проверить это, щелкните внутри поля фрагмента и нажмите Ctrl + S.
Cannicide
1

Это было моё решение, которое намного легче читать, чем другие предложения, может легко включать другие комбинации клавиш и было протестировано на IE, Chrome и 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;
});
Р. Солсбери
источник
1
+1 за использование String.fromCharCode. Хотя у Mac нет управляющего ключа. Проверьте на ключ команды с evt.metaKey. Он возвращается trueдля Cmd на Mac и Win на Windows.
КатоФетт
0

Это должно работать (адаптировано с 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;
    }
}); 
pelms
источник
0

На вопрос Alan Bellows:! (E.altKey) добавлено для пользователей, которые используют AltGrпри наборе текста (например, Польша). Без этого нажатие AltGr+ Sдаст тот же результат, что и 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; });
Яг Фасола
источник
0

Этот плагин, сделанный мной, может быть полезным.

Plugin

Вы можете использовать этот плагин, который вы должны предоставить ключевые коды и функции для запуска, как это

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

В коде я показал, как выполнить для Ctrl+ S. По ссылке вы получите подробную документацию. Плагин находится в разделе JavaScript Code of My Pen на Codepen.

10011101111
источник
0

Я решил свою проблему в IE , используя alert("With a message")для предотвращения поведения по умолчанию:

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;
        }
    }
});
user2570311
источник