14

In my chrome extension's content script, I click on certain links/buttons on webpages from certain sites. To do that, I use following code in the content script (I embed jQuery in the content script):

$(css_selector).trigger("click")

This works on most sites.

However, on certain sites like delta.com, match.com, and paypal.com, this way of triggering a click on elements does not work. On delta.com, I get following exception thrown when I attempt triggering in the content script:

Error: An attempt was made to reference a Node in a context where it does not exist.
Error: NotFoundError: DOM Exception 8

Strange thing is, if I open javascript consoleon delta.com, include a jQuery and attempt the same click triggering code snippet, it works.

On match.com and paypal.com, triggering simply does not work in the content script and there is no error. I cannot even trigger "click" event through javascript console the way I did on delta.com.

If I manually use mouse click, everything works fine on all the three sites. Hence I also tried to simulate that using mousedown(), mouseup(), but that did not work either.

This seems to be issue because javascripts from those sites are hijacking and ignoring events. I tried to read code from these sites to see what is happening but there was simply too much code.

Does anyone have any idea about what is happening here and how to fix it?

Methos
  • 13,608
  • 11
  • 46
  • 49
  • 2
    Possible duplicate: [how to send 'keydown' event to page's input?](http://stackoverflow.com/a/17155170/710446) - jQuery's `click` trigger function does not trigger a non-jQuery DOM click listener (http://jsfiddle.net/k2W6M/). The sites where your code worked may already use jQuery for their listeners, so your jQuery trigger worked. Alternatively, some sites may [check to see if your clicks are actual or programmatic](http://stackoverflow.com/questions/6674669/in-jquery-how-can-i-tell-between-a-programatic-and-user-click). – apsillers Jul 23 '13 at 19:52
  • I checked, `$('li.business a')[0].click()` seems to work on paypal.com home page. – Salman Jul 23 '13 at 22:18
  • @apsillers, thanks. I followed your links and found the answer in the last link. Now I create MouseEvents and dispatch it. That works on all sites. – Methos Jul 25 '13 at 14:18

3 Answers3

26

Due to browser extension sand-boxing, and basic jQuery functionality, you cannot trigger a non-jQuery click event with trigger or click.

You can however call the raw DOM element click method, which will act exactly as if the element was clicked with the mouse. Just use [0] to access the DOM element:

$(css_selector)[0].click();

Although you would seldom need to, you can trigger all matching buttons using the same code in an each. As the this in an each is the DOM element it is quite simple:

$(css_selector).each(function(){
    this.click();
});
iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
13

jQuery's click trigger function does not trigger a non-jQuery DOM click listener (jsfiddle.net/k2W6M).

The jQuery documentation should really point out this fact. I'm sure more than a few people have gone on a wild chase over this.

I was struggling with this same problem for a few days, trying to trigger an onclick handler on a link with .click() and .trigger("click"), all in vain, until I saw this.

For the sake of having a complete answer to this question, dispatching a MouseEvent to the element has the same effect as clicking the element. The following code worked for me, and should work when trying to click an element/link on a page from a content script:

$(css_selector)[0].dispatchEvent(new MouseEvent("click"))
chnrxn
  • 1,349
  • 1
  • 16
  • 17
0

content_script is sandboxed executed,see https://developer.chrome.com/extensions/content_scripts

However, content scripts have some limitations. They cannot:

  • Use variables or functions defined by their extension's pages
  • Use variables or functions defined by web pages or by other content scripts

$ in the content_script can't access $ on the webpage,but the events data stored inner $,so we could not trigger.

// taken from jQuery#1.11.2 from line4571, trigger method
...

// jQuery handler
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
if ( handle ) {
    handle.apply( cur, data );
}

// Native handler
handle = ontype && cur[ ontype ];
magicdawn
  • 27
  • 3
  • What does this code snippet have to do with anything? – Xan Jan 08 '15 at 13:40
  • @Xan suppose `cur` is DOM Object, `jQuery._data(cur,"events")` gets `jQuery.cache[cur[jQuery.expando]].events` , that's shows the `events` data are stored in `jQuery.cache` Object , and it's sandbox executed. So the in our content script , we can't access the webpage's `jQuery` object , cause the `handle` in code above is null. – magicdawn Mar 16 '15 at 02:25