Asynchronous script load issue - javascript

I'm trying to load a script from an external source after the user executes a click function. Like so:
$("#test-button").click(function() {
$.getScript("http://someurl.com/widget/javascript?key=4&t=uid&q=94777&show=all", function (data) {
$('#myDiv').append(data);
});
});
The script I'm loading (which I have no control over) includes a document.write, so I'm getting this error when I execute the click:
It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
I'm not sure how to get around this. I thought getScript would manage this.

It seems like you have append the script like text
please see this example
var script = document.createElement('script');
script.src = '../web3.0/lib/charts/google-charts.js';
document.body.appendChild(script);

Related

How to remove inline styles added by external script?

I have a <script> that generates a both <style> and inline style attributes with !important tags. I'd like to remove all this styling.
My plan was to use a javascript onload callback (and some jQuery) to remove the <style> block and all inline style attributes — but I can't seem to select any of these elements. Here's what I've been toying with:
var script = document.createElement("script");
script.src = "//script.path.js";
script.onload = function(){
$(this).parent().find("style").remove();
$(this).parent().find("[style]").removeAttr("style");
};
$(target).append(script);
UPDATE
It seems that the elements generated by the <script> just aren't available in the DOM right away. If I use setInterval to check if the elements exist first, I can get this to work. I imagine there's a better way to do this though...
According to this other question, you must append the script tag to the DOM before setting onload.
var script = document.createElement("script");
$(target).append(script);
script.src = "//script.path.js";
script.onload = function(){
$(this).parent().find("style").remove();
$(this).parent().find("[style]").removeAttr("style");
};
https://jsbin.com/minoyeyicu/edit?html,js,output
UPDATE: Having clarified that the issue is that the style tag/attributes haven't yet been applied to the DOM until after the downloaded script has executed, one alternative (depending on whether the loaded script is under your control), is to pass a callback parameter to the loaded script and have the loaded script execute the callback when it finishes executing (which is how the Google Maps API works). E.g.
script.src = '//script.path.js?callback=removeStyles'
In order to use the callback parameter from within script.path.js, something like this could be done.

Script doesn't run after load a div with ajax

I have the script audiojs for changing the style of audios tag in html when I go to my page it work without problems, but when I click a button to reload div (this div contain audios tags) with function load jQuery the style of audiojs removed, I tried to get script after load the div with jQuery getScript, but the script load many times that caused to stop of my browser.
this is the function to call the audiojs
audiojs.events.ready(function() {
audiojs.createAll();
});
I want a solution to call this function one time no more, thanks
Try to adding a new script tag to with the script to re-load in your code something like below:
<script language="text/javascript">
function audiojs()
{
var div= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'audiojs.js';
div.appendChild(script);
}
audiojs();
</script>
I hope you will get some ideas now. Also check your caching.
It's hard to know without any link to the audio.js library, but most API's or libraries will give some indication that they are loaded. I would use an if statement to create something like:
(function () {
function checkForLoaded(){
if (audiojs.state !== null) { //or something similar
audiojs.createAll();
}
}
})();
Thanks everyone,
i found the solution,
after loading the div with ajax i added this code to remove the class audiojs
$("audio").removeClass("audiojs");

Count number of async scripts in the DOM

I have a script script.js that calls in advertisements into the DOM. It is invserted after #closeImage if some test is true:
<div id="overlay">
<img id="closeImage" src="close100x100.png">
</div>
If the test is true I call my script.
if (test) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'script.js';
$("#closeImage").append(script);
script.js might not find an advertisement. In this case from within script.js, script01.js which will be inserted into the DOM to look for different advertisements. If nothing is found script03.js will be called from within script02.js and so my div might end looking like this:
<div id="overlay">
<img id="closeImage" src="close100x100.png">
<script src="script.js"></script>
<script src="script01.js"></script>
<script src="script02.js"></script>
<!-- actual banner html -->
</div>
Only the first script is being inserted by the original document.createElement(). How do I count the number of scripts in #overlay? - This did not work:
$(document).ready(function () {
var loaded = $('div#ADF_overlay script').length;
});
EDIT (Restated the problem differently based on feedback)
My main guess here is that you have a timing issue. You are inserting a script, which has to load and then execute, which may then insert another script which has to load and then execute and you don't actually know when that process is done so you can check how many scripts were loaded in total.
$(document).ready() will not wait for that process to be done - it only waits for the original HTML of the document to be parsed (and any inline scripts that were there in the original HTML and don't have the defer or async attributes will run).
The only way to know when a cascade of dynamically loaded scripts are actually done is to have the last script somehow mark when it's done (either by calling a function, triggering an event, setting a variable or marking something in the DOM). Without the script telling you when it's done inserting new script tags, you can't know whether the next script is still loading and waiting to run which might insert some more scripts, etc...
We could probably help better with ideas for solving your overall problem (what you are actually trying to accomplish) if you described the overall problem rather than just this one piece that you're trying to use.
If you just want to count how many dynamically insert scripts there are, then it would be simplest to just maintain a javascript counter as you insert them and then you can use that counter sometime later.
var scriptsInserted = 0;
if (seenOverlay('served') === 'false') {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'script.js';
$("#closeImage").append(script);
++scriptsInserted;
}
Then, some time later, you can just refer to your variable scriptsInserted to access the count.
Alternatively, you can put a class name on your script elements and just query for that:
if (seenOverlay('served') === 'false') {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'script.js';
script.className = "adScript";
$("#closeImage").append(script);
++scriptsInserted;
}
And, some time later:
$(".adScript").length;
If you're dynamically inserting a cascade of scripts (insert one, which loads, runs and then inserts another, and so on), then when do you know to check to see how many scripts were actually inserted? The timing of when to check may also be an issue for you because if you're checking that in $(document).ready(), then that process may not be done yet as each dynamically inserted script is loaded asynchronously and $(document).ready() can easily fire before that process is done because it doesn't wait for dynamically inserted scripts to load or run.
It appears that you may potentially have other issues because inserting a script into a particular place in an already loaded document will usually not insert content at that place in the document because a dynamically loaded script element can't use document.write() to insert content into the existing document in the same way that a normal inline <script> tag can.

Detect whether external script has loaded

Using JavaScript, is there a way to detect whether or not an external script (from a third-party vendor) has completely loaded?
The script in question is used to pull in and embed the markup for a list of jobs and, unfortunately, doesn't make use of any variables or functions. It uses document.write to output all of the content that gets embedded in my page.
Ideally, I'd like to display some kind of loading message while I'm waiting for the external script to load, and if it fails to load, display a "We're sorry, check back later..." message.
I'm using jQuery on the site, but this external script is called before I make the jQuery call.
Here's what the document.write stuff from the external script looks like:
document.write('<div class="jt_job_list">');
document.write("
<div class=\"jt_job jt_row2\">
<div class=\"jt_job_position\">
Position Title
</div>
<div class=\"jt_job_location\">City, State</div>
<div class=\"jt_job_company\">Job Company Name</div>
</div>
");
Attach an function to the load event:
<script type="text/javascript" src="whatever.js" onload ="SomeFunction()" />
As far as your loading... problem goes, try displaying a div for loading and then just display:none-ing it in your onload function. Make sure to handle cases where your script fails to load too, though.
Script tags block downloads, so as long as the content dependent on your script is below where your script it loaded, you should be fine. This is true even if the script is in-line in the body of your page.
This website has a great example of how this works.
This obviously does not work if you're loading the scripts asynchronously.
Scripts without async or defer attributes are fetched and executed immediately, before the browser continues to parse the page.
Source: MDN
You could put a script block after it on the page:
<script src="external_script.js"></script>
<script type="text/javascript">
ExternalScriptHasLoaded();
</script>
Thanks for the assistance above, especially ngmiceli for the Steve Souders link!
I decided to take what's probably a "lazy" approach, and also forego the "loading" message:
$(document).ready(function(){
if ($('.jt_job_list').length === 0){
$('#job-board').html("<p>We're sorry, but the Job Board isn't currently available. Please try again in a few minutes.</p>");
};
});
Pretty simple, but I'm looking to see if an element with the .jt_job_list class is in the dom. If it isn't, I display an error message.
This worked for me: it does however, rely on the newer querySelector interface which most modern browsers support. But if you're using really old browsers, you can use getElement... and run a for loop.
function loadJS(file, callback, error, type) {
var _file = file ;
var loaded = document.querySelector('script[src="'+file+'"]') ;
if (loaded) {
loaded.onload = callback ;
loaded.onreadystatechange = callback;
return
}
var script = document.createElement("script");
script.type = (typeof type ==="string" ? type : "application/javascript") ;
script.src = file;
script.async = false ;
script.defer = false ;
script.onload = callback ;
if (error) {
script.onerror = error ;
}
else {
script.onerror = function(e) {
console.error("Script File '" + _file + "' not found :-(");
};
}
script.onreadystatechange = callback;
document.body.appendChild(script);
}
You could give what ever your looking for an ID
and check whether not the ID has been loaded using document.getElementById("ID");
Is that what your looking for not sure I fully understand?

Dynamic javascript loading and execution

I'm trying to dynamically load a Javascript based on the return value of an API call. I dynamically insert the script tag but it does not get executed. Can someone help understand why? The relevant code snippet is pasted below
onError: function(code) {
if(code == "false") {
var headID = document.getElementsByTagName("head")[0];
var scriptTag = document.createElement("script");
scriptTag.type="text/javascript";
scriptTag.src= 'scriptURL';
headID.appendChild(scriptTag);
}
}
Using firebug/chrome inspector, I can see that the script tag is added to the dom but the script is not executed (at least not that I can determine). It is a 3rd Party script hence I do not have direct control over it and hence cannot modify it either.
After reading the comments below the question it seems that the third party script is doing its job on window.onload event. Many programmers use this style.
window.onload = function() {
// Whatever task
};
If the onload event of your page has already been fired before you add the script tag dynamically, the 'Whatever task' code would never execute.
Check the source of the third party script. If it uses window.onload, you can try calling window.onload(); after you add the script tag dynamically.

Categories

Resources