16

Is there any method that enables me to detect whether a button click was performed by a real user and not some automated method (javascript) that a user has loaded onto their browser developer console or other browser developer tool?

I tried the following methods suggested in various stackoverflow posts but none of them appear to work. REF: How to detect if a click() is a mouse click or triggered by some code?

Script Detection methods tried and failed:

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
    }
})

If I run the following script to trigger the button click from the Chrome browser console none of the methods above traps it as being triggered by a script.

var button = document.getElementById("btnSubmit");
button.click();

==========================================================================

Thank you for all your responses and thanks to stackoverflow for providing such a great site that facilitates so much knowledge sharing and for saving us techies an untold number of hours.

It appears that I still do not have reliable method. All 3 browsers (FF, IE & Chrome) provide a developer/console interfaces for a user to run/inject a javascript on my webpage. It appears that each browser flavor traps some event property values a little differently. For example: Chrome traps the difference between a script activated cick and a real user with e.screenX but in IE: e.screenX has the same value for both a script click (synthetic) and a user button click

The following detection methods either did not work at all or are inconsistent across the different browsers: e.which e.isTrsuted e.originalEvent (event.source != window) (e.distance != null)

The mousedown event appears to be only triggered by a real user button click, but I have to assume there is some script method to emulate a mousedown in addition to a button click event

$(me.container + ' .mybutton').mousedown(function (e) { 
    alert('mouseisdown real button click'); 
}

If anyone can figure out a reliable method that works across multiple browsers, that detects the difference between a synthetic (script) button click and a button click by a user, you will deserve superhero status.

Nisarg Shah
  • 14,151
  • 6
  • 34
  • 55
user151402
  • 311
  • 1
  • 3
  • 7

7 Answers7

15

when a button click happens through the mouse, the event e usually has the mouse pointer location recorded. Try something like :

   if(e.screenX && e.screenX != 0 && e.screenY && e.screenY != 0){
     alert("real button click");
   }
Muhammad Talha Akbar
  • 9,952
  • 6
  • 38
  • 62
Raja
  • 174
  • 4
  • Works for Chrome but not in IE dev console. In IE e.screenX has +values for both manual and scripted button.click – user151402 Feb 11 '13 at 21:09
6

No, it's not possible in all cases.

As other answers mentioned, you can look for the mouse coordinates (clientX/Y and screenX/Y), and if they're not present, you can assume it was probably not a human-generated action.

But, if the user tabs onto the button and uses the space bar to click it, or otherwise clicks it without using a mouse, the coordinates will also be zero, and this method will incorrectly determine it to be a scripted click.

Also, if the script uses dispatchEvent instead of click, coordinates can be given to the event. In this case, this method will incorrectly identify it as a user-generated 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/

Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
5

For security purposes when you trigger an event with javascript it will register differently than if the user triggered the event. Console log the ev object and you will see significant differences between the two cases.

mybutton.click(function(ev) {
  console.log(ev);
});

Here are some sample output of the two cases:

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
Kyle Weller
  • 2,533
  • 9
  • 35
  • 45
  • 1
    This is a drag example, the question states a question on click event. – Ja͢ck Feb 10 '13 at 04:28
  • In Chrome on the button.click event: e shows (e.originalEvent.type == 'mousedown') for both a scripted click and a real click. Are there any other properties that will be different and consistent across different browsers? – user151402 Feb 11 '13 at 23:54
  • How about [ev.isTrigger](http://stackoverflow.com/questions/10704168/in-javascript-what-is-event-istrigger) – Kyle Weller Feb 11 '13 at 23:58
3

Use "event.isTrusted" to know event is triggered from Javascript or User click.

Sample Code:

<!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>
Seshu Vuggina
  • 725
  • 1
  • 8
  • 16
1

Fiddle Here.

$("button").mousedown( function(e) {
    if(e.which) {
        alert(1);
    }
});
$("button").trigger("mousedown");

Or Javascript:

document.getElementsByTagName('button')[0].onmousedown = function(e) {
 if(e.which) {
    alert(1); // original click
 }
}
document.getElementsByTagName('button')[0].onmousedown();

You can see in the fiddle, it will not let trigger function to call but only when mouse is down on button. If automated click is triggered on button then e.which is undefined which can be trapped easily.

UPDATE : Fiddle For Javascript

Muhammad Talha Akbar
  • 9,952
  • 6
  • 38
  • 62
0

Event object have a nativeEvent object which contains isTrusted field.

Its value will be false when event is not triggered by real user. So you can check if real user clicked the button by -

if(event.nativeEvent.isTrusted){
    //Real user
} else {
    //Triggered by script
}
codegsaini
  • 87
  • 6
0

I solve this problem adding data attribute to element, then check if this attribute is present ( means trigered by script) and remove the attribute

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', '');
})})
Marcin Żurek
  • 145
  • 1
  • 3