检测按钮是否单击真实用户或由脚本触发

时间:2013-02-10 03:25:45

标签: javascript events onclick

是否有任何方法可以让我检测是否真实用户执行了按钮点击,而不是某个用户已加载到浏览器开发者控制台或其他浏览器开发者工具上的自动方法(javascript)?

我尝试了各种stackoverflow帖子中建议的以下方法,但它们似乎都不起作用。 参考:How to detect if a click() is a mouse click or triggered by some code?

脚本检测方法尝试失败:

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提供如此优秀的网站,以促进如此多的知识共享,并为我们的技术人员节省数不清的时间。

看来我还没有可靠的方法。所有3种浏览器(FF,IE和Chrome)都为用户提供开发者/控制台界面,以便在我的网页上运行/注入javascript。看起来每个浏览器风格都会略微捕获一些事件属性值。例如:Chrome使用e.screenX捕获脚本激活的cick和真实用户之间的差异,但是在IE中:e.screenX对于脚本单击(合成)和用户按钮单击具有相同的值

以下检测方法要么根本不起作用,要么在不同的浏览器中不一致: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'); 
}

如果有人能够找到一种适用于多种浏览器的可靠方法,它可以检测合成(脚本)按钮点击和用户点击按钮之间的区别,那么您将获得超级英雄状态。

5 个答案:

答案 0 :(得分:11)

当通过鼠标点击按钮时,事件e通常会记录鼠标指针位置。尝试类似:

   if(e.screenX && e.screenX != 0 && e.screenY && e.screenY != 0){
     alert("real button click");
   }

答案 1 :(得分:5)

不,在所有情况下都不可能。

正如其他提到的答案,您可以查找鼠标坐标(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/

答案 2 :(得分:3)

出于安全考虑,当您使用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

答案 3 :(得分:0)

Fiddle此处。

$("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未定义,可以轻松捕获。

更新: Fiddle For Javascript

答案 4 :(得分:0)

使用“ 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>