How-to load a dynamically appended script that won't load? - javascript

Dynamically appended script never loads:
const nodeTemplate = document.importNode(template.content, true)
const script = nodeTemplate.firstElementChild
script.removeAttribute('async')
script.setAttribute('defer', 'defer')
document.body.appendChild(nodeTemplate)
Any idea why? Is there a way to force it to load?
I've looked around at diverse solutions here and elsewhere and none seem to work as of now.
It works fine if it happens at page load.

I think you need to check whether it's loaded or not, if not, better to remove completely that script from the DOM, and then create new script tag.
And then try something like this, it's common pattern to inject script widgets:
// 1. remove your old script
// 2. create new
(function(){
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = false;
s.defer = true;
s.src = "https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js";
document.getElementsByTagName('head')[0].appendChild(s);
})();

Related

Javascript onload not firing in IE11

I'm creating a new window using the following:
var windowX = window.open('page.html', 'newWindow', 'width=600,height=600');
The new window is just a blank html page that contains javascript which constructs a new object, I then use that object with some more javascript that I inject after the page has loaded.
My solution works in chrome and firefox but does not appear to work in IE11. The alert does not show, nor does the following code.
windowX.onload = function() {
//I've added the alert just to see if the onload is firing...
windowX.alert('hello!');
var script = document.createElement('script');
script.type = 'text/javascript';
script.language = 'JavaScript';
script.src = '/scripts/newScript.js';
windowX.document.head.appendChild(script);
};
I've attempted to use jQuery $(windowX).ready(...) & $(windowX).load(...) which still works in chrome but with no success in IE11.
I figured out the problem is that IE11 runs window.open() as a synchronous task, preventing any further javascript from running until the window has opened and loaded, so the onload event that is declared afterwards is never fired because the new window has already 'loaded'.
To get around this I check if the users browser is IE11 and fire the load event using jquery:
if (!!window.MSInputMethodContext && !!document.documentMode) {
$(windowX).trigger('load');
}
It is ok - you cannot work with properties of unfinished object ("Unable to set property 'onload' of undefined or null reference"), but this code works in IE11 (do not need to load empty page):
var windowX = window.open('');
windowX.alert('hello!');
var script = windowX.document.createElement('script');
script.type = 'text/javascript';
script.language = 'JavaScript';
script.src = '/scripts/newScript.js';
windowX.document.head.appendChild(script);
But you are right those 2 browsers have them visible during loading (for example window.name does not exist in IE, but exist in these 2).

Remove/Prevent .js file in JavaScript

Hi I am working with a webservice and I have to manipulate the design to make it look better. Recently I had to make it work on IPad.
So my Problem is my edit's don't work in Iphone because the service adds if its a mobile device a viewport and an extra .js file. This is causing unwanted changes. So is there a way to prevent the system from loading / opening? I can use Javascript to do this. My recent trys was to get the "IPhone.js" and make it empty
var scriptElements = document.getElementsByTagName("script");
var patt = /iPhone.js/g;
var sourceOfElement = "";
for (var i = 0; i < scriptElements.length; i++) {
sourceOfElement = scriptElements[i].src;
if (patt.test(sourceOfElement)) {
scriptElements[i].src = "";
};
This didn't really worked because the IPhone.js is loaded before I can "make it empty".
Another try was to remove the viewport, this also did't worked.
So anybody have any idea how to prevent the service from loading/executing the IPhone.js?
can you add iphone.js via javascript not script tag?
It will be something like this:
if (shouldILoad) {
(function() {
var myscript = document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = ('iphone.js');
var s = document.getElementById('myscript');
s.parentNode.insertBefore(myscript, s);
})();
}
If you don't want iphone.js to execute just add a return statement at the start of the iphone.js file if condition is matched
iPhone.js
if(YOUR_CONDITION_NOT_TO_EXECUTE_IPHONE_JS) return; //check for your condition and return
//Other iphone.js code

Unbind .onselectstart return false

I am trying to write a userscript that will remove the effects of onselectstart from an id on a page.
So far I am assuming that I can rebind the original function using something like this:
document.getElementById('nodrag').onselectstart = function() { /* code original action */ };
JSFiddle
Any ideas would be appreciated.
Looks like I managed to work out the answer. Thank you LightStyle for giving me the hints.
So I create an script tag with document.getElementById('nodrag').onselectstart = function() { }; inside it and append this to the body.
// Create the script to remove the nodrag from chrome
var script = document.createElement('script');
script.type='text/javascript';
script.innerHTML = "document.getElementById('nodrag').onselectstart = function() { };";
var body = document.getElementsByTagName('body')[0];
body.appendChild(script);
This might not work in traditional contexts however works a charm on a userscript. Here is the final script:
https://gist.github.com/lgoldstien/5928021

“too much recursion” in onload event

I am trying to include a form from one page on one domain to another page on another domain. Here is my code which I put after my block form.
function IncludeSrc(src) {
var s= document.createElement("script");
s.src = src;
s.async = true;
document.getElementsByTagName("head")[0].appendChild(s);
}
var onLoadFunc = window.onload;
window.onload=function(){
if (typeof(onLoadFunc)=='function') onLoadFunc();
IncludeSrc('MYADRESS');
};
There is no error in any browser but the form does not load. In Firefox console I found the error too much recursion. The address of the script is valid, I checked it. What am I doing wrong?
That's because you're calling onLoadFunc within itself. Regardless of why you'd want to do this, there's no base case for the recursion, so it never bottoms out...

Ordered JavaScript File Loading

I need to dynamically load several JavaScript file assets in a very specific order after a page has loaded. I'm trying to use onload, but this seems to fire before the asset has fully loaded. How should I adjust the below script to fire a proper callback to load the next script?
Note: Only needs to work in the latest Chrome, Firefox, Safari, and IE9.
function loadAssets() {
// Setup script
var scriptJS = document.createElement('script');
scriptJS.type = 'text/javascript';
scriptJS.src = objectUrl;
scriptJS.onload = loadAssetsNext();
// Begin insertion
var headerJS = document.getElementsByTagName('HEAD');
headerJS[0].appendChild(scriptJS);
},
function loadAssetsNext() {
// Increment object counter
objectsCount++;
// Test to see if you should call another item
if ((objectsCount) < objects.length) {
// Setup script
var scriptJS = document.createElement('script');
scriptJS.type = 'text/javascript';
scriptJS.src = nextObjectUrl;
// Declare callback to fire after script has fully loaded
scriptJS.onload = loadAssetsNext();
// Begin insertion
var headerJS = document.getElementsByTagName('HEAD');
headerJS[0].appendChild(scriptJS);
}
}
What I need is something like scriptJS.fullyLoaded = doStuff. Have no clue where to go from here though.
PS: jQuery is not an option or another library. You should be able to do this by slightly modifying the above script.
The reason your onload event is firing immediately is that you are calling it, not assigning it.
scriptJS.onload = loadAssetsNext();
This just assigns the returned value from the call to loadAssetsNext to the property onload of the scriptJS object. What you are intending to do is:
scriptJS.onload = loadAssetsNext;
That sets the onload handler to be the loadAssests function. This should take care of your issues.
I think the problem is that your scriptJS.onload = loadAssetsNext(); is placed before headerJS[0].appendChild(scriptJS);
That means that your scripts would load and get appended to the page like this:
load script 1
load script 2
load script 3
...
append script 3
append script 2
append script 1
So I think you should just reorder your script a little bit.

Categories