检测按钮是点击真实用户还是由脚本触发
Detect if button click real user or triggered by a script
有没有任何方法可以让我检测按钮点击是否是由真实用户执行的,而不是用户加载到浏览器开发人员控制台或其他浏览器开发工具上的某种自动方法(javascript)?
我在各种stackoverflow帖子中尝试了以下方法,但似乎都不起作用。REF:如何检测click()是鼠标点击还是由某些代码触发?
脚本检测方法尝试但失败:
mybutton.click(function (e) {
if (!e.which) {
//Triggered by code NOT Actually clicked
alert(' e.which - not a real button click')
} else if ('isTrusted' in e && !e.isTrsuted) {
//Triggered by code NOT Actually clicked
alert(' e.isTrusted - not a real button click')
} else if (e.originalEvent === undefined) {
//Triggered by code NOT Actually clicked
alert(' e.originalEvent - not a realbutton click')
}
// else if (!e.focus) {
// //triggered // does not detect e.focus on a real btn click
// alert(' e.focus - not a realbutton click')
// }
else {
// Button hopefully clicked by a real user and not a script
}
})
如果我运行下面的脚本从Chrome浏览器控制台触发按钮点击,上面的任何方法都不会将其误认为是由脚本触发的。
var button = document.getElementById("btnSubmit");
button.click();
=================================================
感谢您的回复,感谢stackoverflow提供了一个如此伟大的网站,促进了如此多的知识共享,并为我们的技术人员节省了无数的时间。
看来我还是没有可靠的方法。所有三种浏览器(FF、IE和Chrome)都为用户在我的网页上运行/注入javascript提供了开发人员/控制台界面。似乎每个浏览器风格捕获的一些事件属性值略有不同。例如:Chrome捕获了脚本激活的cick和使用e.screenX的真实用户之间的差异,但在IE中:e.screeneX对脚本点击(合成)和用户按钮点击具有相同的值
以下检测方法要么根本不起作用,要么在不同的浏览器中不一致:e.which e.isTrsuted e.originalEvent(event.source!=window)(e.distance!=null)
mousedown事件似乎只由真正的用户点击按钮触发,但我必须假设除了按钮点击事件之外,还有一些脚本方法可以模拟mousedown
$(me.container + ' .mybutton').mousedown(function (e) {
alert('mouseisdown real button click');
}
如果有人能找到一种可靠的方法,可以在多个浏览器中工作,检测合成(脚本)按钮点击和用户按钮点击之间的差异,那么你将获得超级英雄的地位。
当鼠标点击按钮时,事件e通常会记录鼠标指针的位置。试试类似的东西:
if(e.screenX && e.screenX != 0 && e.screenY && e.screenY != 0){
alert("real button click");
}
不,不可能在所有情况下都这样。
正如前面提到的其他答案一样,您可以查找鼠标坐标(clientX/Y和screenX/Y),如果它们不存在,您可以假设可能不是人为生成的操作。
但是,如果用户点击按钮并使用空格键单击它,或者在不使用鼠标的情况下单击它,坐标也将为零,并且这种方法将错误地确定它是脚本化的单击。
此外,如果脚本使用dispatchEvent
而不是click
,则可以为事件提供坐标。在这种情况下,此方法将错误地将其标识为用户生成的单击。
// This will produce what appears to be a user-generated click.
function simulateClick(element) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 110, 111, 10, 11, false, false, false, false, 0, null);
element.dispatchEvent(evt);
}
http://jsfiddle.net/bYq7m/
为了安全起见,当您使用javascript触发事件时,它的注册方式与用户触发事件时不同。控制台记录ev
对象,您将看到这两种情况之间的显著差异。
mybutton.click(function(ev) {
console.log(ev);
});
以下是两种情况的一些示例输出:
jQuery.Event
currentTarget: button
data: null
delegateTarget: button
handleObj: Object
isTrigger: true
jQuery191011352501437067986: true
namespace: ""
namespace_re: null
result: undefined
target: button
timeStamp: 1360472753601
type: "mousedown"
__proto__: Object
jQuery.Event {originalEvent: MouseEvent, type: "mousedown", isDefaultPrevented: function, timeStamp: 1360472840714, jQuery191011352501437067986: true…}
altKey: false
bubbles: true
button: 0
buttons: undefined
cancelable: true
clientX: 39
clientY: 13
ctrlKey: false
currentTarget: button
data: null
delegateTarget: button
eventPhase: 2
fromElement: null
handleObj: Object
isDefaultPrevented: function returnFalse() {
jQuery191011352501437067986: true
metaKey: false
offsetX: 37
offsetY: 11
originalEvent: MouseEvent
pageX: 39
pageY: 13
relatedTarget: null
screenX: 1354
screenY: 286
shiftKey: false
target: button
timeStamp: 1360472840714
toElement: button
type: "mousedown"
view: Window
which: 1
__proto__: Object
使用"event.isTrusted";以了解事件是由Javascript或用户点击触发的。
样本代码:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<input type="text" id="myInput">
<button id="myBtn" onclick="callFunction(event)">Click Me</button>
<script>
function callFunction(event) {
console.log(event.isTrusted); // true only when user clicks 'Click Me' button
}
window.onload = function () {
let event = new Event("click");
callFunction(event); // false
}
var input = document.getElementById("myInput");
// Execute a function when the user releases a key on the keyboard
input.addEventListener("keyup", function (event) {
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById("myBtn").click(); // false
}
});
</script>
</body>
</html>
在此处拖动。
$("button").mousedown( function(e) {
if(e.which) {
alert(1);
}
});
$("button").trigger("mousedown");
或者Javascript:
document.getElementsByTagName('button')[0].onmousedown = function(e) {
if(e.which) {
alert(1); // original click
}
}
document.getElementsByTagName('button')[0].onmousedown();
你们可以在小提琴上看到,它不会让触发器函数调用,但只有当鼠标按下按钮时。如果按钮上触发了自动点击,则e.which
未定义,很容易被捕获。
更新:Javascript 的Fiddle
Event对象有一个包含isTrusted
字段的nativeEvent
对象。
当事件不是由真实用户触发时,其值将为false
。所以你可以通过-来检查真正的用户是否点击了按钮
if(event.nativeEvent.isTrusted){
//Real user
} else {
//Triggered by script
}
我解决了向元素添加数据属性的问题,然后检查该属性是否存在(意味着由脚本触发)并删除属性
let element = document.getelementbyid('btn');
//set before triggering
element.setAttribute('data-triggered-by-script', '1');
element.click();
element.onClick(function(e){if (e.target.getAttribute('data-triggered-by-script' == 1){
//do when triggeted by script
e.target.setAttribute('data-triggered-by-script', '');
})})
- 当包含另一个asp文件时,是否也包含所有引用的样式和脚本页面
- 借助asp.net验证或java脚本对多个文本进行验证
- chrome扩展:尽管运行了at:documentidle,js脚本还是过早启动
- Java脚本时间添加
- 不显示带有本地json文件数据的谷歌地图脚本
- JQuery添加元素需要在我的js之前再次添加JQuery脚本
- 从远程脚本获取用户IP
- 如何根据时间运行不同的脚本
- 如何将字符串值从php页面发送到java脚本页面
- 使用谷歌应用程序脚本将服务器端数据表返回到客户端
- 可以设置“;文件名"发生错误时显示的内联脚本标记的
- 当脚本由system.js加载时,如何要求('electron')
- HTML标记在脚本标记中工作
- 是否可以控制获取哪些Google地图脚本(JavaScript API)
- 使用谷歌应用程序脚本从工作表中获取值并将其显示在文本框中
- 显示时间的脚本
- ng应用程序使脚本无限运行
- 如何在运行时在angular 2中加载外部js脚本
- 如何在我们知道 ajax 加载元素的真实高度(带有图像)后立即执行脚本
- 检测按钮是点击真实用户还是由脚本触发