jQuery在触发按键事件时会重复触发两次的问题

6

我正在开发一个视频播放器,希望能通过键盘控制基本的视频操作,如播放、暂停、快进。这是我使用的代码,用于获取键盘事件:

$("#video_container_div").on("keypress", function (e) {
    e.preventDefault();
    e.stopPropagation();
    switch (e.which) {
    case 32:
        { // space
            console.info("I am in keyboard controls");
            $("#playpausebtn").click();
            break;
        }
    default:
        return;
    }
});
$("#fullscreenbtn").click(function () { //bind click event on fullscreen button
    console.info("I am in fullscreen")
    fullscreenFun();
});

现在我面临的问题是,如果用户点击全屏按钮,然后按空格键,事件将被触发两次。 http://202.164.44.244/products/trunk/video_player/sample1.htm 首先它会播放/暂停视频,然后自动触发全屏或任何最后聚焦的事件。
如果我按了全屏按钮,然后按空格键,控制台就会显示这个:
I am in fullscreen
I am in keyboard controls
I am in fullscreen  

在另一个堆栈问题中,有人给出了类似问题的答案。

https://stackoverflow.com/a/17936661/1652512

这是播放器的链接:

http://202.164.44.244/products/trunk/video_player/sample1.htm

但我需要具体的解决方案。这个问题已经占据了我的一整天。


1
你能提供 Plunkr 链接吗? - Anik Islam Abhi
fullscreenFun(); 是什么意思? - Evan Knowles
我刚刚编辑了问题并提到了链接,请看一下。 - Arjun Thakur
1个回答

3
最终编辑:抱歉这花了一点时间,现在已经是午夜了,我有些疲倦。
你使用了错误的事件!忽略我之前关于焦点的说法,只需将“keypress”替换为“keydown”,它就可以正常工作。焦点将保持在全屏按钮上,但是您的事件将正常工作,并且e.stopPropagation()足以防止事件多次触发。您的代码应该是这样的:
$("#video_container_div").on("keydown", function (e) {
    e.preventDefault();
    e.stopPropagation();
    switch (e.which) {
        case 32:
        { // space
            console.info("I am in keyboard controls");
            $("#playpausebtn").click();
            break;
        }
        default:
            return;
    }
});
$("#fullscreenbtn").click(function () { //bind click event on fullscreen button
    console.info("I am in fullscreen")
    fullscreenFun();
});

我感觉你在事件多次触发时使用stopPropagation有点奇怪。

值得注意的是,当video_container_div或其内部元素获得焦点时才会触发此事件。如果没有使用JavaScript(例如可以调用.trigger("keydown")),则"keydown""keypress"需要获取焦点才能触发。如果有人专注于页面上的其他元素或刚刚打开页面(没有任何焦点),那么"keydown"事件将不会触发。


当您单击全屏按钮时,它会使全屏按钮获得焦点,因此当您按下空格键时,它会触发您创建的keypress事件并被视为单击,因为许多浏览器认为当某个元素处于焦点状态时,按下空格键或回车键相当于单击操作。

试着添加

$("#video_container_div").focus();

到你的最后
$("#fullscreenbtn").click(function () { 

事件将焦点从全屏按钮元素移除,查看其是否仍会触发两次。

编辑:我查看了您网站上的确切代码,我添加了这个代码并且它对我起作用了。

$(h + t.$fulScrnBtn).click(function () { //bind click event on fullscreen button
    fullscreenFun();
    $(h + t.$plyBtn).focus();
});

然而,这样做的原因并不是您最终想要的。所有这些只是将播放/暂停按钮置于焦点状态,因此当某人按下空格键时,浏览器会将其视为对该按钮的点击,而不是因为有人在聚焦视频时按下了空格键。


好的,我看了一下你网站上的代码,并编辑了对我有效的部分。 - Colwyn Fritze-Moor
它正在工作,但我做了一个小改变,不再将焦点放在$playBtn上,而是放在视频上。因为将焦点放在$playBtn上会产生相同的问题。否则感谢您的帮助 :) - Arjun Thakur
没问题。我用更好的解决方案进行了最后一次编辑,我完全是个笨蛋,忽略了一些简单的东西。那会起作用! - Colwyn Fritze-Moor
在关注另一个元素时,不要忘记在该元素中添加“tabindex =”1“”。 - Arjun Thakur

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