Loading your JavaScript after an external JS get executed - javascript

I've a problem that is a bit tricky over here, I'm trying to apply a simple JQuery line of code that addClass to a div with class pop-up
but the problem is that class pop_up is not accessible after jQuery(document).ready(function($){});
This class is actually added from an external JS and the pop_up functionality
is also added from an external JS so I'm wondering
How To Add The Class using JQuery after the external JS get executed so pop_up class can be found using:
$('.pop_up');
What I've tried:
jQuery(document).ready(function($) {
$('.pop_up').addClass('importantRule');
$('.pop_up').toggleClass('importantRule');
});
this is not working as the external JS added the class somehow after .ready, so if you tried to print out $('.pop_up') it will be undefined.
I've also tried to look for the class using a constant class container of div.pop_up like this:
$('div.element').find('.pop_up').addClass('importantRule');
that didn't work either, I know for a fact the problem is with calling the function in .ready as some how the external JS get executed after it so,
is there away around this?
if not, is there a way to detect if all of external JS files are ready and loaded?

You can have $(document).ready() multiple times in a page. The code gets run in the sequence in which it appears.
You can use the $(window).load() event for your code since this happens after the page is fully loaded and all the code in the various $(document).ready() handlers have finished running.
$(window).load(function(){
//your code here
});

One way is to use a setTimeout to check:-
function checkForElement() {
setTimeout(function() {
if ($('.pop_up').length) {
$('.pop_up').addClass('importantRule');
} else {
checkForElement();
}
}, 100);
}
checkForElement();
This will wait for 100ms, then check. if its not there then it will wait again, and again, etc.

You experience a race condition. If the external script finishes running first, then your code will work, but if your code finishes first, then it breaks.
You can either hack around it like Satej S suggested on the comments, and give a reasonable timeout which will make sure the external script finished running, and after that timeout, run your script.
setTimeout(function(){ doSomething(); }, 3000);
A better solution will be using a callback from the external script (can you edit the external script?). This way, the second the external script ends, it calls for one of your internal functions that will start working.

To avoid timeouts that most other answers suggest, I would advise you to try adding "defer" tag to your script include. That way the script trying to add class "importantRule" will wait until all of the other scripts have been loaded and executed.

In addition, I found this question quite similar
load and execute order of scripts
Hope this helps! Thanks

Related

JavaScript function after page load and other JS/Ajax function completion [duplicate]

I was using $(window).load(function(){}); for my projects until somewhere I saw that somebody said we could just use $(function(){}); and they would perform identically.
But now that I have more experience I have noticed that they are not identical. I noticed that the first piece kicks in a little bit after the second piece of code.
I just want to know what's the difference?
$(document).ready(function(){})
will wait till the document is loaded(DOM tree is loaded) and not till the entire window is loaded. for example It will not wait for the images,css or javascript to be fully loaded . Once the DOM is loaded with all the HTML components and event handlers the document is ready to be processed and then the $(document).ready() will complete
$(window).load(function(){});
This waits for the entire window to be loaded. When the entire page is loaded then only the $(window).load() is completed. Hence obviously $(document).ready(function(){}) finishes before $(window).load() because populating the components(like images,css) takes more time then just loading the DOM tree.
So $(function(){}); cannot be used as a replacement for $(window).load(function(){});
From the jQuery docs itself.
The first thing that most Javascript programmers end up doing is adding some code to their program, similar to this:
window.onload = function(){ alert("welcome"); }
Inside of which is the code that you want to run right when the page is loaded. Problematically, however, the Javascript code isn't run until all images are finished downloading (this includes banner ads). The reason for using window.onload in the first place is that the HTML 'document' isn't finished loading yet, when you first try to run your code.
To circumvent both problems, jQuery has a simple statement that checks the document and waits until it's ready to be manipulated, known as the ready event:
$(document).ready(function(){
// Your code here
});
Now,
$(window).load(function(){}); is equal to window.onload = function(){ alert("welcome"); }
And, $(function(){}); is a shortcut to $(document).ready(function(){ });
I think , this clears everything :)
$(window).load from my experience waits until everything including images is loaded before running where as $(function() {}); has the same behaviour as $(document).ready(function() {});
Please someone correct me if I am wrong.
The second is/was a shortcut for $(document).ready(), which should run before window's load event.
Note that $(document).ready() is the preferred way of binding something to document load; there are a couple other ways of doing it like the one you showed, but that's preferred.

loading a js file asynchronously from a js file that loads asynchronously

I had a javascript file(initial.js) on the page inserted through the script tag like so:
<script src="initial.js"></script>
This file creates dom elements(let say two links) and also loads another jQuery plugin(plugin.js) asynchronously via jQuery ajax method. Clicking on those two links brings up a module from the jQuery plugin(plugin.js).
The javascript file(initial.js) was then modified to load asynchronously on the page via jQuery ajax instead of via script tag. This has resulted in some events not getting attached to the links intermittently and this results in the plugin not being called.
I believe the browser is loading the async scripts in its own order and hence the links fail to launch the plugin intermittently. Any pointers to resolve this issue with this new set up?
At a high-level, I think you need to look into something like require.js. Alternatively, you could look into some jQuery event handling code which allows you to listen on load events of calls which may help you determine when one script loaded before loading the next one.
You have probably tried something like this in the past:
var output;
$.get('data.php',function(data){
output=data;
});
alert(output);
You will get an undefined error because Javascript doesn't wait around for the AJAX call to be returned before moving onto the next code.
Same thing goes for scripts. If you place multiple calls to multiple scripts, you will probably get the smallest one returned the quickest, and that script executed. If you load a script that is 10kb and then one that is 1kb, the 1kb script will probably return the quickest and then be executed even though it was called after the 10kb script.
To correct this, you could make a queue system and then only load each script after the previous has loaded:
var scripts=['script1.js','script2.js','script3.js'];
$(document).ready(function(){
loadScript();
});
function loadScript(){
if(sendQueue.length==0)
return;
$.getScript(scripts[0],function(){
scripts=scripts.slice(1);
loadScript();
});
}
But if you are loading scripts from within scripts from within scripts... very Inception like, then this still may not work.

Question about when a script is executed after appending it

In my code, I have javascript that dynamically adds another script to the page:
created_script=document.createElement('script');
created_script.src='other_script';
created_script.type='text/javascript';
document.head.appendChild(created_script);
in this 'other script', I have a function called reloader().
The problem I'm having is that right after I dynamically add the script, I try to call the function reloader(), but I'm getting a reloader is not defined error.
Here's is like what I am doing:
created_script=document.createElement('script');
created_script.src='other_script';
created_script.type='text/javascript';
document.head.appendChild(created_script);
reloader();
Can someone explain to me why this doesn't work and how should I fix this so that reloader() can be called after appending the script in a single dynamic call (if possible at all)?
Loading scripts like this happens asynchronously. This means that at the time you call reloader(), the external script may still be loading.
Your script shouldn't invoke loader() until it knows that the external script has completely loaded. See this related question: How can I delay running some JS code until ALL of my asynchronous JS files downloaded?

$.getScript() and $(window).load() in Safari 5 not always working

I'm experiencing a similar problem to this guy except my problem is related to scripts and not images.
I'm using a combination of $.getScript() and $(window).load() to load JavaScript dynamically and use functions that are being loaded once the script has completely finished loading.
It works well in Chrome but Safari seems to always fire the onload event too early. I was wondering if there was some way to force Safari to wait for all scripts to load similarly to the document.body.offsetWidth block. From what I understood (and from the results I saw when I tested it), document.body.offsetWidth blocks until styles and images are loaded but apparently not scripts.
Edit: It might be worth mentioning that it does work in Safari sometimes but I don't see a pattern. Sometimes the event is fired before the script is fully loaded and executed and the handler passed $(window).load() fails because the functions are missing.
Based on the comments you have made, specifically those surrounding dependencies, I would use a library like RequireJS. This will give you what you need to import scripts and their dependencies, and also hooks to call functions and code when dependencies are met.
Have you tried the good old document ready?
$(document).ready(function() {
//code here
})
I've never had any issues when using that. Worst case scenario, you can drop a script tag after all your other script tags that include the code you require.
In this example, I tell loaded scripts that I need to do something to report loaded to a function. Once all that I need are loaded, I run whatever code I need to.
// Simplified callback to check for all scrips loaded.
var numDynScriptsReady = 0,
numDynScriptsNeeded = 4;
function dynScriptsReady()
{
numDynScriptsReady++;
if( numDynScriptsLoaded == numDynScriptsNeeded )
{
// Run functions you need after loaded....
}
}
// Example script get
$.getScript( "http://example.com/script.js", dynScriptsReady );
// etc....

Loading Javascript through an AJAX load through jQuery?

I have an javascript that I place into a page using the code below. What the code does is place an object/embed code into a webpage. Simple javascript loader to a NicoVideo movie
<script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/sm13154955?w=640&h=395"></script>
This works great in a webpage. But what if I want to load this javascript into a page using AJAX? This no longer works for the obvious reasons, you would need to eval the script in order to get it to run. However, I have no idea how to do this. I am using jQuery on my page; so keep that in mind. I have tried the following code, but it doesn't seem to work through AJAX, or even in a normal page load environment.
<script>$.getScript("http://ext.nicovideo.jp/thumb_watch/sm13154955?w=640&h=395");</script>
Any ideas on how I would get this to work?
I think it works but its attempting to inline the write which I don't know if that would work in this case.
You would need to see if there was a way to essentially execute the '.getHTML' method and take that result and update an existing element on the page.
The issue though is that the anonymous function that is generated and executed inline might not work properly.
After reading official getScript reference, it seems you have to do something with that JS file you got a hold of, using something like this:
$.getScript("http://ext.nicovideo.jp/thumb_watch/sm13154955?w=640&h=395", function () {
// use functions from loaded file
});

Categories

Resources