Javascript触发两个事件 - onkeypress和onclick。

6

问题是,当我在单选按钮上按下键时,元素MyFunc会触发两次——一次为onkeypress事件,另一次为“click”事件。

问题是“为什么?”我需要以两种不同的方式处理此问题,但现在我无法识别最初的事件是什么。当我点击鼠标时,它只会触发“click”事件。

<ul>
    <li>
        <input type="radio" onkeypress="MyFunc(event, this)" onclick="MyFunc(event, this)" name="myList" id="MyId_1" />Topic 1
        <input type="radio" onkeypress="MyFunc(event, this)" onclick="MyFunc(event, this)" name="myList" id="MyId_2" />Topic 2
    </li>
</ul>

function MyFunc(e, obj) {
    alert(e.type); // alerts "keypress" and then "click"
    // Do my stuff
}
8个回答

3

如果在按键过程中触发了2个事件,则在onClick函数中检查 event.detail 属性。 如果 event.detail = 0,那么就意味着鼠标没有在该元素上单击,我们可以忽略它。 event.detail


1
可以做到而不必诉诸于通常笨重缓慢的框架。诀窍是记录事件发生的时间点,然后在此基础上在一个时间范围内工作。当你触发“keypress”事件时,“click”事件会立即触发,在这里是一个列表,显示了“click”事件在“keypress”事件之后多快被触发...
Chrome 39.0:0毫秒
Firefox 31.0 ESR:18~20毫秒
IE 11:2~4毫秒
Opera 12.1:0毫秒
Chrome和(真正的)Opera不等待,IE相当快,Firefox需要一些时间;至少在我的系统上,可用的范围是0~20毫秒。从编程角度来看,我将限制设置为50毫秒,以适应那些仍在使用150个无用后台进程的垃圾计算机的人。
请注意,您必须利用“window”全局级别的事件,尽管在我提到的所有浏览器中,这似乎对我都是可靠的。
var option = new function() {this.name = '';}


window.onclick = function(event)
{
 option.clickDate = new Date().getTime();
}


window.onkeypress = function(event)
{
 option.keyCode = event.keyCode;
 option.keyCodeDate = new Date().getTime();
}


function MyFunc(e,obj)
{
 if (option.keyCodeDate && option.clickDate && 
 (
  (option.clickDate - option.keyCodeDate)>=0 && 
  (option.clickDate - option.keyCodeDate)<51)
 {alert('keypress event');}
 else {alert('click event');}
}

1

onclick事件在单选按钮被选中时触发。由于您通过按键选择它,因此两个事件都将被触发。首先是onkeypress事件,然后是onclick事件。


但是你如何防止这种情况发生? - Todd Moses
据我所知,你无法阻止此行为。 - Aurril
这很奇怪。一起处理这些事件有什么意义呢?:-/ - podeig

0

你可以在你的函数中添加第三个参数

function MyFunc(e, obj, click) {
    if (click) { } // do stuff
    else { } // do other stuff
}

现在在你的事件中添加一个布尔值...

<input type="radio" onkeypress="MyFunc(event, this, false)" onclick="MyFunc(event, this, true)" name="myList" id="MyId_1" />Topic 1
<input type="radio" onkeypress="MyFunc(event, this, false)" onclick="MyFunc(event, this, true)" name="myList" id="MyId_2" />Topic 2

问题在于它们同时触发。我可以使用 e.type 属性识别所点击的内容。它会返回 "keypress" 或 "click"。 - podeig

0
我会创建两个不同的处理程序:一个用于单击事件,另一个用于按键事件。
然后,您的处理程序可以从事件中提取您需要的任何内容,并调用一个具有通用逻辑的第三个函数。
您的onkeypress必须忽略空格键和回车键的事件。 我不明白为什么您要监听keypress事件。 您能详细说明吗? 如果您解释您要做什么,也许我们可以更有帮助。

0
一个关键事件是为了让仅使用键盘的用户激活按钮,但如果您使用按钮,则只需要“click”事件,因为按下空格键时会触发它。如果您在自定义控件上有事件,“key”事件和“click”事件都可以使用,且不会同时触发。

0

我已经查看了建议的属性.type.detail。在Firefox和Chromium上,type保持为click。在Chromium上,detail保持为0,但是在Firefox上实际点击鼠标时会更改为1。但是,当使用鼠标单击时,.x.y在Firefox和Chromium上都会更改,而在事件源自键盘操作时仍保持为0


-1
使用JavaScript中的onMouseDown而不是onclick,并为了一致性在此处添加您的onKeyPress事件 - 从HTML标记中删除事件。
伪代码:
var myRadioButton = document.getElementById('radio');

myRadioButton.addListener("radioClick",onMouseDown);
myRadioButton.addListener("radioKey",onKeyPress);

radioClick()
{
 //code to do stuff
}

看看jQuery:http://jquery.com/,它提供了实际的代码和编写JavaScript的简便方式。


我会尝试一下。我想我用了 onMouseDown,但是它的效果像 OnClick。也许 addListener 会有所帮助。我很快就会回来并带来结果。 - podeig
我已经尝试使用jQuery解决此问题,但没有帮助。 "OnMouseDown" 没有触发任何事件,它只是没有调用我的函数。如果我使用 addListener 和 "OnClick",它会出现相同的问题。目前我还没有任何解决方案。有什么想法吗? - podeig
很好,你提到了一致性,但是你却通过建议一个框架来破坏了它。如果我通过谷歌搜索这个问题,这个页面不会出现,因为我使用jQuery来寻找答案,而不是向用户倾泻带宽。请坚持使用真正的JavaScript。 - John

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