检查事件是否由人触发


140

我有一个附加到事件的处理程序,我希望它仅在由人触发而不是由trigger()方法触发时执行。我该如何区分?

例如,

$('.checkbox').change(function(e){
  if (e.isHuman())
  {
    alert ('human');
  }
});

$('.checkbox').trigger('change'); //doesn't alert

Answers:


212

您可以检查e.originalEvent:如果已定义,则点击是人为的:

看看小提琴http://jsfiddle.net/Uf8Wv/

$('.checkbox').change(function(e){
  if (e.originalEvent !== undefined)
  {
    alert ('human');
  }
});

我在小提琴中的例子:

<input type='checkbox' id='try' >try
<button id='click'>Click</button>

$("#try").click(function(event) {
    if (event.originalEvent === undefined) {
        alert('not human')
    } else {
        alert(' human');
    }


});

$('#click').click(function(event) {
    $("#try").click();
});

1
@Nicola这个文件记录在任何地方吗?
森那维达斯

@Sime我不知道,但我认为这是标准的。看这里:api.jquery.com/category/events/event-object
Nicola Peluchetti

@Nicola我知道,这是一个jQuery的东西。jQuery将原始事件对象存储在此属性中。顺便说一句,你什么意思你不知道?你只是提供链接到文件:)
森那维达斯

1
看起来您也可以使用event.isTrigger
avoliva

1
@Anurag,我刚才遇到了同样的问题。originalEvent当事件由触发时,jQuery似乎填充了jQuery DOM.click(),但是您可以使用$($("#try")[0]).click();,这很笨拙,但是可以使用。
丹尼尔·加勒特


7

我认为,这样做的唯一方法trigger是根据文档在调用中传递一个附加参数。

$('.checkbox').change(function(e, isTriggered){
  if (!isTriggered)
  {
    alert ('human');
  }
});

$('.checkbox').trigger('change', [true]); //doesn't alert

示例:http//jsfiddle.net/wG2KY/


1
您可以检出事件对象的属性originalEvent:如果事件不是来自单击,则它是未定义的
Nicola Peluchetti


1
由于某些原因,当使用Zepto的“单击”处理程序时,event.originalEvent对我不起作用(只是一直重播1)。所以我尝试了上面的解决方案。像魅力一样工作。
Larrydx

7

接受的答案对我不起作用。已经6年了,自那时以来jQuery发生了很大变化。

例如,event.originalEvent始终true使用jQuery 1.9.x 返回。我的意思是对象始终存在,但内容不同。

那些使用较新版本的jQuery的人可以尝试使用此版本。适用于Chrome,Edge,IE,Opera,FF

if ((event.originalEvent.isTrusted === true && event.originalEvent.isPrimary === undefined) || event.originalEvent.isPrimary === true) {
    //Hey hooman it is you
}

3

当前大多数浏览器都支持event.isTrusted

if (e.isTrusted) {
  /* The event is trusted: event was generated by a user action */
} else {
  /* The event is not trusted */
}

文档

接口的isTrusted只读属性Event是a Boolean ,当事件由用户操作生成时为true,而 由脚本创建或修改事件或通过EventTarget.dispatchEvent()调度事件时为 false


0

您可以使用onmousedown来检测鼠标单击与Trigger()调用。


在以下情况下,我可能无法工作:有时可以使用Tab键选择页面的元素。例如,如果以这种方式选择了一个复选框,则可以使用空格键进行选中/取消选中。甚至可以使用向下箭头键打开drodpdown。
Diego Favero

0

我会考虑一下您检查鼠标位置的可能性,例如:

  • 请点击
  • 获取鼠标位置
  • 重叠按钮的坐标
  • ...

在以下情况下,我可能无法工作:有时可以使用Tab键选择页面的元素。例如,如果以这种方式选择了一个复选框,则可以使用空格键进行选中/取消选中。甚至可以使用向下箭头键打开drodpdown。
Diego Favero

0

柜面你有你的所有代码,没有外来的呼叫控制$(input).focus()setFocus()

对我来说,使用全局变量是正确的方法。

var globalIsHuman = true;

$('input').on('focus', function (){
    if(globalIsHuman){
        console.log('hello human, come and give me a hug');
    }else{
        console.log('alien, get away, i hate you..');
    }
    globalIsHuman = true;
});

// alien set focus
function setFocus(){
    globalIsHuman = false;
    $('input').focus();
}
// human use mouse, finger, foot... whatever to touch the input

如果某个外星人仍然想$(input).focus()从另一个星球打电话。祝你好运或查看其他答案


这只会阻止人们拨打电话setFocus()-不会阻止人们触发焦点事件。完全不编写文字setFocus()也会阻止人们调用它,因此我看不出有什么好处。实际上,人们仍然可以致电$('input').focus()并通过。
罗伯

哇,我第一次回答问题后马上有个人评论,我将更新答案
vanduc1102

如果您在没有其他/第三方脚本的封闭环境中工作,那么这将是一个完美的世界。但是,大多数实际应用程序是针对客户端站点的,这些站点上添加了各种插件和脚本,这些插件和脚本很可能会引起关注。可能有助于解决此问题的一件事是将您的代码(以及需要调用该函数的所有代码)包装在如下这样的作用域函数中:(function(){/*your code here*/})();这样可以防止setFocus函数被调用,而布尔值则可以被外部脚本更改。
Xandor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.