Difference between .click() and actually clicking a button? (javascript/jQuery)

18,404

Solution 1

I use this function to truly mimic a mouse click:

function clickLink(link) {
    var cancelled = false;

    if (document.createEvent) {
        var event = document.createEvent("MouseEvents");
        event.initMouseEvent("click", true, true, window,
            0, 0, 0, 0, 0,
            false, false, false, false,
            0, null);
        cancelled = !link.dispatchEvent(event);
    }
    else if (link.fireEvent) {
        cancelled = !link.fireEvent("onclick");
    }
}

Solution 2

Before reading the below, which discusses how to circumvent the problem, let me answer more fully why you're having the problem to begin with:

Modern browsers take different actions for links based on things like which mouse button you clicked with, whether you held Shift / Ctrl / Alt, and so on. As an example, in Chrome, if you middle-click a link instead of left-clicking, the browser will automatically open the window in a new tab.

When you use .click(), jQuery has to make assumptions about the "way" in which you clicked - and you get defaulted behavior - which in your case, is not the correct behavior. You need to specify the "correct" settings to the browser in the form of MouseEvents settings in order to fix the issue.

Now, on to a short discussion of ways to fix it:

When you are using jQuery's .click() event with no parameters, this is not actually "faking a click" on the element in question. Instead, according to the jQuery documentation at http://api.jquery.com/click/ :

... when .click() is called without arguments, it is a shortcut for .trigger("click")

This means that when you fire $('#div1').click() - if there is no actual jQuery handler for the 'click' event, you will get default processing. So, consider these two cases:

Case 1:

<a id='myLink' href='/some/link/'>Click me!</a>
<script type='text/javascript'>
    $('#myLink').click();
</script>

In this first scenario, the .click() call does nothing, because there is no handler for it. The event triggers, but there is nothing to catch it and respond - so the a tag's default handling is used, and the user is taken to /some/link/ - and since you haven't specified which mouse button or any other parameters - it's truly default.

Case 2:

<a id='myLink' href='/some/link/'>Click me!</a>
<script type='text/javascript'>
    $('#myLink').bind('click', function (ev) {
        ev.preventDefault();
        ev.stopPropagation();

        alert('you clicked me!');
    }).click();
</script>

In this scenario, because a click handler was created, when the user clicks the link - the ev.preventDefault() and ev.stopPropagation() calls will stop the default handling from occuring, and the alert will be fired.

At this point, however, you have an ev object which represents the MouseEvents - and you could change the settings if you desired. For instance, you could do the following:

ev.altKey = true; // Held Alt
ev.button = 1;    // Middle Mouse Button

These settings will change the default method of handling the event.

Alternative, non-jQuery solution

You can also truly simulate a button-click by adapting the following code.

function fakeClick(event, anchorObj) {
  if (anchorObj.click) {
    anchorObj.click()
  } else if(document.createEvent) {
    if(event.target !== anchorObj) {
      var evt = document.createEvent("MouseEvents"); 
      evt.initMouseEvent("click", true, true, window, 
          0, 0, 0, 0, 0, false, false, false, false, 0, null); 
      var allowDefault = anchorObj.dispatchEvent(evt);
      // you can check allowDefault for false to see if
      // any handler called evt.preventDefault().
      // Firefox will *not* redirect to anchorObj.href
      // for you. However every other browser will.
    }
  }
}

(For a more full implementation, see the original post at: How can I simulate a click to an anchor tag? - and look at the selected answer)

This will actually fake the browser into believing that you mouse-clicked the anchor / span / etc by building the event from scratch in the same way that the browser's default handlers do - except that you can override some of the settings. I don't suggest this approach, however, as it's a lot more prone to breaking on cross-browser application and you have to figure out what all of the parameters map to.

Solution 3

  $('img').click(function(event){
    console.log(event.hasOwnProperty('originalEvent')); // output : true

  });
  $('img').trigger("click",function(event){
    console.log(event.hasOwnProperty('originalEvent')); // output : false

 });

Solution 4

To create and trigger a click event same as user-click :

function simulateClick() {
  var event = new MouseEvent('click', {
    view: window,
    bubbles: true,
    cancelable: true
  });
  var cb = document.getElementById('checkbox');  //whichever element you want to click
  var cancelled = !cb.dispatchEvent(event);
  if (cancelled) {
    // A handler called preventDefault.
    alert("cancelled");
  } else {
    // None of the handlers called preventDefault.
    alert("not cancelled");
  }
}

of course, call the function like this.

simulateClick();

Source : https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

note : initMouseEvent() is deprecated. Avoid using it, instead use MouseEvent() as shown in this solution.

Share:
18,404

Related videos on Youtube

Goose
Author by

Goose

I'm a developer living in Phoenix, AZ; currently working at a software consulting company in Scottsdale. I come to SO every time I need help, so if I'm able I like to try to help others as well.

Updated on July 14, 2022

Comments

  • Goose
    Goose almost 2 years

    I'm trying to figure out this weird issue I've been having, and the root cause is the difference between a live click and triggering .click().

    I won't get into the details of the problem, but basically when you click on the input button it works fine (has an onclick event). But if I call .click() from somewhere else (instead of physically clicking the button) it doesn't work properly.

    My question is - is there a way to truly replicate an actual click on a button?


    EDIT

    The problem: I'm opening a new window (aspx page) that loads an inline PDF. If I actually click on the link, the window opens fine and the PDF loads. If I use .click() the window opens and I'm prompted to download the PDF file. I've been through Adobe Reader settings, browser settings, and registry settings about the prompting - I understand that these can be factors to the big picture, but right now I'm concerned about why the behavior between a mouse click and .click() are doing anything different at all.

    • Mathletics
      Mathletics almost 12 years
      "I won't get into the details of the problem"... but that's what we do here. Sounds like something else isn't working, because .click() should trigger a click.
    • Ry-
      Ry- almost 12 years
      Could be that the button is submitting a form when clicked (I don't remember whether this works with click or not), or maybe that it handles mouseup and/or mousedown events instead of click.