使用JQuery捕获CTRL+S的最佳跨浏览器方法是什么?

175

我的用户希望能够通过按下 Ctrl+S 来保存表单。有没有一种良好的跨浏览器的方式来捕获 Ctrl+S 组合键并提交表单呢?

应用程序是基于Drupal构建的,因此可以使用jQuery。

17个回答

271

以下是我使用Jquery的一种方法,用于重载Ctrl+SCtrl+FCtrl+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。 - T. Brian Jones
35
如果你使用window.addEventListener(而不是$(window).bind(,则可以使用纯JS完成。 - user1846065
2
@NatesS 如果你移除警告,它就不会打开保存对话框。这是由于警告引起的。在所有浏览器中都可以正常工作。很好的解决方法。 - CrazyNooB
2
对我有用。请接受这个答案而不是上面的那个。 - pavanw3b
1
@Fireflight:使用“else if”是不行的,因为原始的“if”语句已经被判断为真。你需要将你的代码放在原始的“if”语句之前,将原始的“if”语句转换为“else if”。 - Danny Ruijters
显示剩余4条评论

125
$(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没有注册任何按键。 - pelms
7
即使使用$(document).keypress(而不是$(window).keypress),IE和Chrome仍然会在脚本之前捕获带有'Ctrl'的按键事件。 - pelms
17
在Chrome浏览器中,请使用keydown替代keypress - destan
3
很遗憾,它已经过时了。 - Cannicide
显示剩余6条评论

34

你可以使用一个快捷键库来处理浏览器特定的问题。

shortcut.add("Ctrl+S",function() {
    alert("Hi there!");
});

7
这已经被转换为一个 jQuery 插件,并进行了分叉和再次分叉,现在支持 1.6.x:https://github.com/ricardovaleriano/jquery.hotkeys - Félix Saparelli
12
对于Google员工,jQuery插件的更新后网址为:https://github.com/jeresig/jquery.hotkeys - bgs264

30

这个jQuery解决方案在Chrome和Firefox中对我有效,同时支持Ctrl+SCmd+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
这是唯一一个在这里正常工作的解决方案。非常感谢! - Stephan Weinhold
2
这个可能已经过时了:使用 e.key 而不是 e.which; - Cannicide
更新于2017年5月14日,符合现代标准。 - Alan Bellows

29

这个方法在Chrome上对我有效...由于某种原因,event.which 对我返回的是一个大写的 S(83),不确定为什么(无论大写锁定键状态如何),所以我使用了 fromCharCodetoLowerCase 以确保安全。

$(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,请告诉我,如果有人在其他浏览器上测试它是否有效,我也很乐意听到反馈。


我在使用Chrome时也遇到了同样的问题,真是太痛苦了! - qodeninja
现在看来,我认为preventDefault是多余的,因为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;
     }
});

6

$(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答案的最新版本,用key替换了which。即使在Chrome的大写键故障下也可以使用(按下Ctrl+S发送大写S而不是小写s)。适用于所有现代浏览器。

5
我希望Web应用程序不要覆盖我的默认快捷键。老实说,在浏览器中,Ctrl+S已经有了特定的功能。如果这种快捷键因为我访问的网站不同而突然改变,那么这将是令人烦恼和不稳定的,更何况常常会出现错误。我曾经遇到过一些网站劫持Ctrl+Tab,因为它看起来和Ctrl+I一样,这不仅破坏了我的工作,也防止我像往常一样切换选项卡。
如果您需要快捷键,请使用accesskey属性。请不要破坏现有浏览器功能。

2
我完全同意,但不幸的是我只是负责实施,而不是决策者。 - ceejayoz
26
没错,但是CTRL+S不是一个常用的功能。我怀疑人们不会太在意它是否存在,特别是如果它意味着你可以在网络应用程序中保存文件。 - EndangeredMassa
17
通常我同意你的观点,但我在浏览器中唯一使用Ctrl-S的时候是当我忘记我正在使用一个Web应用程序,并期望这个快捷键做一些有用的事情时。通常我会感到失望。当你按下Ctrl-S时,Gmail会保存你的电子邮件,尽管你可能不会注意到,因为它只是按照你的期望和每个桌面应用程序所做的事情,你并不会真正注意到。但当它认为你想将Gmail保存为HTML时,你会注意到它很烦人。 - Carson Myers
4
这实际上取决于具体应用场景。我正在开发一个终端模拟器Web应用程序,覆盖 ctrl+c 的操作似乎是切实可行的,如果不是必须的话也是可以的。 - Brack
1
让从未意外按下Ctrl + S提交表单的人先举石头。 - KevBurnsJr
显示剩余2条评论

4

@Eevee: 随着浏览器成为丰富功能的家园并开始取代桌面应用程序,放弃使用键盘快捷键将不再是一个选择。Gmail丰富而直观的键盘命令集对我放弃Outlook的意愿起到了关键作用。Todoist、Google Reader和Google Calendar中的键盘快捷键都使我的日常生活变得更加轻松。

开发人员一定要注意不要覆盖浏览器中已有含义的按键。例如,我正在输入的WMD文本框莫名其妙地将Ctrl+Del解释为“块引用”,而不是“向前删除单词”。我很好奇是否有一个标准列表,列出了网站开发人员可以使用的“浏览器安全”快捷键,而浏览器将承诺在未来版本中避免使用这些快捷键。


1
答案是否定的,没有一份浏览器安全快捷键列表是安全的。这样做有两个好处:
  1. 快捷键是可自定义的(至少在Opera中)。
  2. 这样做,你不会限制浏览器厂商创造力,从而为浏览器本身的使用赋予更多的能力。
- gizmo

1

我喜欢这个小插件,但是它需要更好的跨浏览器兼容性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接