在jQuery中,如何区分程序化点击和用户点击?


91

假设我定义了一个点击处理程序:

$("#foo").click(function(e){

});

我如何在函数处理程序中判断事件是通过编程方式触发还是由用户触发?


程序如何以编程方式触发事件?
克莱顿

5
为什么需要区分案例?
Damien_The_Unbeliever

@Clayton:$x.click()$x.trigger('click')
亩太短了,

我遇到了一种使用图像滑块的情况,该滑块会自动滚动图像,并通过触发与该图像相关联的正确导航项的点击来实现。问题是,当用户单击导航时,自动旋转应停止。
卡萨波,2012年

2
这适用于最新的Firefox,Chrome和IE9。为什么不接受以下投票数最高的答案?@kevino
OZZIE 2013年

Answers:


119

您可以看一下事件对象e。如果该事件是由一个真实的点击触发的,你有喜欢的东西clientXclientYpageXpageY,等内e,他们将是数字; 这些数字与触发点击时的鼠标位置有关,但是即使点击是通过键盘启动的,这些数字也可能会出现。如果事件是由触发的,$x.click()则您将不会具有通常的排名值e。您也可以看一下originalEvent属性,如果事件来自的话,该属性不应存在$x.click()

也许是这样的:

$("#foo").click(function(e){
    if(e.hasOwnProperty('originalEvent'))
        // Probably a real click.
    else
        // Probably a fake click.
});

这是一个可以使用的小沙箱:http : //jsfiddle.net/UtzND/


4
太棒了……我只是对自己说:“也许jQuery触发的事件没有鼠标位置信息”!w00t!
卡萨波,2012年

2
这可以在支持createEvent的浏览器中击败。 jsfiddle.net/UtzND/26
Joe Enzminger 2012年

2
@JoeEnzminger是的,但是为什么您会打败自己的脚本呢?
OZZIE

3
我担心第三方脚本会生成click事件,而我的脚本会在假定它是用户生成(实际点击)的情况下对其进行处理。
Joe Enzminger 2013年

2
@JoeEnzminger:一旦您的代码在浏览器中,所有的赌注都消失了,您无法做的任何事情都不会被足够聪明的人打败。我认为您能做的最好的事情就是检查一堆东西:有originalEvent吗?这是对的吗?哪里有坐标?坐标是否一致?坐标在里面#foo吗?...
亩太短了

44

您可以使用jQuery触发手册中所述的额外参数:

$("#foo").click(function(e, from){
    if (from == null)
        from = 'User';
    // rest of your code
});

$('#foo').trigger('click', ['Trigger']);

3
我看到的唯一问题是您无法区分普通点击和$x.click().click()呼叫者必须明确告诉您他们是在伪造它。取决于凯文·奥沃基(Kevin Owocki)的工作,这可能是问题,也可能不是问题。
亩太短了,

1
@mu:我不太了解您在“正常”点击(用户?)和$x.click()eventHandler(对于用户点击,可能是“正常”)之间的
区别

1
不同之处在于,一个来自用户,而另一个来自软件。虚假点击可能来自插件或其他一些无法修改以添加额外参数的代码。我没有批评您的解决方案,只是指出了一些可能的漏洞。
亩太短了

尽管亩是正确的,但这在每种情况下都行不通,但这正是我一直在寻找的东西,谢谢!不知道我可以像var这样传递额外的参数,但这正是我需要在复杂的UI中测试“真实”点击的条件,该界面将某些“真实”点击视为程序化。感谢您提供了两个非常有用的解决方案!
菲尔(Phil)


5

我已经尝试了上述所有解决方案。下面的解决方案为我工作。希望它也会对您有帮助。

$(document).ready(function(){
  //calling click event programmatically
    $("#chk1").trigger("click");
});

$(document).on('click','input[type=checkbox]',function(e) {
		if(e.originalEvent.isTrusted==true){
			alert("human click");
		}
		else{
			alert("programmatically click");
		}
    
    });
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js">
</script>

<input type="checkbox" id="chk1" name="chk1" >Chk1</input>
<input type="checkbox" id="chk2" name="chk2" >Chk2</input>
<input type="checkbox" id="chk3" name="chk3" >Chk3</input>


4

DOM级别3指定event.isTrusted。IE9 +和Firefox当前仅支持此功能(根据我的测试。我还阅读(尽管没有进行深入研究)它可以在某些浏览器中覆盖,并且可能还没有100%准备好被信任(不幸的是)。

是@mu小提琴的修改版本,可在IE和Firefox上使用。


好点子。我认为任何事情都不会是100%可靠的。您必须混入一些测试以查看是否isTrusted受支持且不可写。我认为真正的答案取决于该问题背后的原因,而我们从未找到原因。
亩太短

@mu,我问了一个类似但更笼统的问题后才想到这个问题。我的“为什么”情况是,我希望确保仅在用户在页面上直接采取了肯定的行动后,才执行某项操作(一项财务交易,尽管很小)。
Joe Enzminger 2012年

1

Vanila js解决方案:

document.querySelector('button').addEventListener('click', function (e){
    if(e.isTrusted){
        // real click.
    }else{
        // programmatic click
    }
});

-1

不想参加学术讨论,对我有用的代码可以过滤,.click()并且.trigger('click')是-

$(document).on('click touchstart', '#my_target', function(e) {
    if (e.pageX && e.pageY) { // To check if it is not triggered by .click() or .trigger('click')
        //Then code goes here
    }
});
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.