Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery .on not working with dynamic DOM/HTML

Tags:

I'm not exactly sure if this is due to my manifest setup, or if there's something going on with the .on event and pages that generate content/modify content on the fly, but I've run into a stumbling block.

Here's the basic idea: I want to be able to catch a click on any link with a URL that matches a pattern regardless of where the user is/what page they're looking at (and do other stuff instead of navigating to the link). The problem I'm running into is that my listener won't work on any page that modifies its content after content loads (jQuery's $(document).ready) (e.g. gMail). I'm injecting my javascript all over the place and it's still not quite working.

Here's the listener code (in main.js):

$('a[href^="http://www.google.com/calendar/event?action=TEMPLATE"]').on('click', function(event)  {   event.preventDefault();   SKDMmain(this); }); 

Here's the code in my background.html: (injects my script when the page loads as well as when the tab/window is changed to, so it should be there. Note: jQuery is included above, along with all of the local .js files I need)

<script type="text/javascript">   $(document).ready( function(){     chrome.tabs.executeScript(null,{file:"main.js"});   });   chrome.tabs.onActiveChanged.addListener( function(tabID,somethingElse){       chrome.tabs.executeScript(tabID,{file:"main.js"});   });       chrome.windows.onFocusChanged.addListener( function(windowID){     if ( windowId != chrome.windows.WINDOW_ID_NONE ) {       chrome.tabs.executeScript(null,{file:"main.js"});      }   }); </script> 

But in pages like gMail or this, the listener doesn't catch the event. I originally had this as a content script, but I recently moved it to using background and programmatically injecting, but neither seem to be working quite right.

Here's my manifest, for reference:

{ "name": "SkedjoolMi", "version": "0.5", "description": "Automated Google Calendar event scheduling", "background_page": "background.html", "permissions": [   "tabs","http://*/","https://*/" ], "content_scripts": [   {     "matches": ["<all_urls>"],     "js": ["jquery-1-7-1.js"],     "run_at": "document_end",     "all_frames": true   } ] } 
like image 976
Brad Orego Avatar asked Jan 15 '12 02:01

Brad Orego


People also ask

Does jQuery work on dynamic content?

In fact, for following jQuery code . on() works for even dynamically added elements. As here, before the event is attached, the dynamic div is already appended to the HTML body: $(document).

How do you bind change event in jQuery for dynamically added HTML element?

If you try to bind the elements that are dynamically added to the DOM using the click() method of jQuery, this will not work, because it only binds the click event to elements that exist at the time of the “binding”. To bind the click event to all existing and future elements, use jQuery's on() method.

Is jQuery static or dynamic?

The reason to work jquery with static content is they are known to DOM, and can handle the events of known elements. but with dynamic contents you have to bind the event with that element by using .


1 Answers

$('a[href^="http:.......').on('click', function() { ... 

Will only work with anchors that are already present when the page is rendered—not dynamically added anchors. The above is exactly identical to

$('a[href^="http:.......').bind('click', function() { ... 

Here's how you use on with dynamically added content:

$(document).on("click", 'a[href^="http://www.google.com/calendar/event?action=TEMPLATE"]', function() ... 

This creates a delegated event. All clicks that happen in descendants of your document (which is everything) will be inspected to see if the source of the click matches your selector. If it does, your event will fire. That's why it works with dynamically added content.

Ideally, if you can guarantee that all of these anchors will be inside of some container, say, a div with id foo, the follow would be more efficient:

$('#foo').on("click", 'a[href^="http://www.google.com/calendar/event?action=TEMPLATE"]', function() ... 
like image 126
Adam Rackis Avatar answered Sep 30 '22 05:09

Adam Rackis