MAX POWER
MAX POWER

Reputation: 5448

jQuery - detect change event triggered programmatically

I have a jQuery change event for when a user changes a given SELECT element. However the event may also be triggered by a third party script. What I want to do is detect whether the event was triggered programmatically or by the user.

I have tried the accepted solution in this question Check if event is triggered by a human But note the JSFiddle in this answer is for a click event rather than a change event.

To demonstrate I amended the fiddle and created this one: http://jsfiddle.net/Uf8Wv/231/

If you try this in latest Firefox or Chrome, you will see that the alert human is being shown even when the event was triggered programmatically.

I have tried event.originalEvent.isTrusted but that doesn't work in all browsers. Can anyone help?

Upvotes: 5

Views: 5019

Answers (6)

Jaber Al Nahian
Jaber Al Nahian

Reputation: 1061

What really worked for me is:

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

Tested with jQuery version 3.5

Upvotes: 1

Julien Grégoire
Julien Grégoire

Reputation: 17124

You can listen to the click event as well, and modify a variable. The change event seems indeed to be quite similar wheter it's a real click or a script triggered click, but the click on #try event won't be the same. And since click is triggered before change, you have time to set a switch. Like this for example:

var realClick;
$("#try").change(function(event) {
  console.log('change')
  if (!realClick) {
    alert('not human')
  } else {
    alert(' human');
  }

});

$("#try").click(function(event) {
  console.log('click')
  // originalEvent is one way, but there will be many differences
  if (event.originalEvent) {
    realClick = true;
  } else {
    realClick = false;
  }
});

// Since this is called from outside, better not put 
// any controls here.
$('#click').click(function(event) {
  $("#try").click();
});

http://jsfiddle.net/2xjjmo09/3/

Upvotes: 1

Alex Kudryashev
Alex Kudryashev

Reputation: 9460

You can find some vague difference between click and emulated click using this code:

$(document).on('change', "#try", function (event) {
    //some difference appear in the next line
    console.log(event.delegateTarget.activeElement);
    //no difference
    if (event.originalEvent === undefined) {
        alert('not human')
    } else {
        alert(' human');
    }
    event.delegateTarget = null;//doesn't help

});

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

Click on the checkbox logs <input id="try" type="checkbox">.
Click on the button logs <button id="click">.
But...
Run $("#try").click(); from console before any clicks logs <body> and after the click result of the last click.
Generally JS can always fake any client event. So isTrusted is never trusted.

Upvotes: 1

Nishanth Matha
Nishanth Matha

Reputation: 6081

You can check for if event.srcElement (which is source element on which event is triggered) is equal to event.currentTarget something like:

$("#try").change(function(event) {console.log(event,event.target,event.currentTarget,event.srcElement)
    if (event.currentTarget=== event.srcElement) {
        alert(' human')
    } else {
        alert(' not human');
    }
});

Fiddle: http://jsfiddle.net/Uf8Wv/234/

Upvotes: 0

choz
choz

Reputation: 17858

You can easily detect whether the click event on the button is actually triggered by mouse click or not. By doing,

$('#click').click(function(ev) {
    if (ev.which !== undefined && ev.button !== undefined) {
        $("#try").click();
    }
});

Here's the Fiddle

Note: Beware of either ev.which or ev.button could result in 0 on some browser for left-click.

Upvotes: 0

brandon
brandon

Reputation: 595

I have added mouseenter and mouseleave events. The idea is that it's a human if the click coincided with a mousepointer being over the element. See: http://jsfiddle.net/Uf8Wv/232/

$("#try").mouseenter(function(event) {
    mouseover = true;
});
// ... etc.

I can't think of any other way.

Upvotes: 1

Related Questions