Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery script file loading twice

Tags:

jquery

ajax

When I submit a form using Ajax I want to reload the section of the page that has changed, rather than the whole page, and for this I'm using:

$('#body_container').load(a_href);

where a_href is the location of the source file. After this command has run and #body_container is updated, the new content of the div doesn't seem to be able to access the script files included in the header of the original page, even though it is encompassed by this original page. It only works if I put <script type="text/javascript" src="files.js"></script> at the start of the a_href file.

However, I actually have little divs inside #body_container that I'm also changing, so doing it this way I have files.js being included lots of times at different levels. It seems to be causing conflicts.

Is there a way to include files.js once in the document header, then have all divs, regardless of when their content was created, always recognise that this file is there, waiting to be used?

like image 597
dplanet Avatar asked May 28 '13 00:05

dplanet


2 Answers

Including the same JS file in every load is a bit much. My suggestion would be to include the file in the main head the first time. Then make use of "delegation" for "dynamic" elements.

For example, say I'm loading a view partial that will have link buttons similar to the initially loaded ones. thus I want them to maintain the same click function. Instead of typical assignment, such as:

$("a.bob").click(function(e) { e.preventDefault(); alert($(this).prop("href")); });

I will use "delegation". jQuery gives us an easy way to do this that will assign the SAME EVENT|METHOD TO ALL ITEMS (PRESENT AND FUTURE[DYNAMIC]) HAVING MATCHING SELECTOR. The way to do this is like:

$(document).on("click", "a.bob", function(e) {
    e.preventDefault();
    alert($(this).prop("href"));
});

The previous will tell ALL a tags having the class bob to not go any where and alert me of their link. This is regardless of when the a tag was added to the DOM.

Example

One thing to keep in mind, .on is new as of jQuery version 1.72 (i think). Prior to that you would use .live or even .delegate instead.


On a Side-Note

Of course, delegation is only going to work with "events". If you need to use JavaScript for something like "layout" movement, then you're best to make a "callback" function to be used with the success of an ajax request. Again, you can place these callback methods in your one head file, but you will need to "call" them as needed in either $.ajax[success or complete].

See success and complete http://api.jquery.com/jQuery.ajax/ to learn more about the basic callbacks of an ajax call. Also, as of version 1.7, you can maintain a list or jQuery Object of callbacks to be fired as needed. To get more information about callback lists, see http://api.jquery.com/category/callbacks-object/

If this is not enough information, please comment and I'll try to make anything you have a question on more clear.

like image 67
SpYk3HH Avatar answered Oct 13 '22 22:10

SpYk3HH


Is the actual problem that the event handlers in your script don't work in the dynamically loaded content?

If that's the case, change those event handlers to use event delegation. For example:

$("#body_container").on( 'click', '#my-div', function() {...});

Or:

$("#body_container").delegate( '#my-div', 'click', function() {...});

where #my-div is some element in the dynamic content.

Now the event handler will work even though you only load the script once when the page is first loaded.

like image 36
Michael Geary Avatar answered Oct 13 '22 22:10

Michael Geary