“too much recursion” in onload event - javascript

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...

Related

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

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);
})();

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).

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.

Create Script Tag Within Javascript and Call Function Right After

I have some code where I am trying to include a script file and then call a function inside the script file. The code is:
function includeJS(p_file) {
var v_js = document.createElement('script');
v_js.type = 'text/javascript';
v_js.src = p_file;
document.getElementsByTagName('head')[0].appendChild(v_js);
}
function checkFlash(){
includeJS('/scripts/swfobject.js');
var playerVersion = swfobject.getFlashPlayerVersion();
return playerVersion.major;
}
alert(checkFlash());
The problem is it is failing at checkFlash() where it tries to get the player version. I checked firebug and it shows the script is loaded and its reading the file correct, so its not a path issue.
I thought that maybe it was a delay issue in the includeJS function, but when I would that code in before the alert without it being a function, it still gives the same problem.
Any ideas on how I would accomplish something like this?
Thanks.
I think your problem is that the script file doesn't finish loading before you attempt to check the player version (just like you originally thought). You might want to try this:
function includeJS(p_file, callback) {
var v_js = document.createElement('script');
v_js.type = 'text/javascript';
v_js.src = p_file;
v_js.onreadystatechange = callback;
v_js.onload = callback;
document.getElementsByTagName('head')[0].appendChild(v_js);
}
function checkFlash(){
var playerVersion;
includeJS('/scripts/swfobject.js', function () {
var playerVersion = swfobject.getFlashPlayerVersion();
alert(playerVersion.major);
});
}
checkFlash();
This is a modified version of the solution presented in the accepted answer to this similar question.

How to run a javascript function using the # in the url?

hi this all started when i ran a function (lets call it loadround) that altered the innerHTML of an iframe. now once loadframe was loaded there were links in the iframe that once clicked would change the iframe page. the only problem is when i click the back button the loadround page was gone. i've thought about this numerous times to no avail. so i tried this code.
loadround
then
function loadround(a,b){
window.location.hash = "#loadround('"+a+"','"+b+"')";
var code = "<(h2)>"+a+"</(h2)><(h2)>"+b+"</(h2)>"
var iFrame = document.getElementById('iframe');
var iFrameBody;
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0]
iFrameBody.innerHTML = code;
}
(the brackets in the h2 are intentional)
then i would try to reload the function by possibly an onload function but for now i was testing with a simple href as followed.
function check(){
var func = location.hash.replace(/#/, '')
void(func);
}
check
unfortunately the check code doesn't work and im almost certain there is an easier way of doing this. i tried changing the src of the iframe instead of the innerhtml and there was the same problem. thanks in advance
The modern browsers are starting to support the event window.onhashchange
In the meantime you can use the workaround proposed by Lekensteyn or maybe you can find something useful here: JavaScript/jQuery - onhashchange event workaround
You are misunderstanding the function void, which just make sure the return value is undefined. That prevents the browser from navigating away when you put it in a link. You can test that yourself by pasting the next addresses in your browser:
javascript:1 // note: return value 1, browser will print "1" on screen
javascript:void(1) // note: undefined return value, browser won't navigate away
It's strongly discouraged to execute the hash part as Javascript, as it's vulnerable to XSS without proper validating it. You should watch the hash part, and on modification, do something.
An example; watch every 50 milliseconds for modifications in the hash part, and insert in a element with ID targetElement an heading with the hash part. If the hash part is not valid, replace the current entry with home.
var oldHash = '';
function watchHash(){
// strip the first character (#) from location.hash
var newHash = location.hash.substr(1);
if (oldHash != newHash) {
// assume that the parameter are alphanumeric characters or digits
var validated = newHash.match(/^(\w+)$/);
// make sure the hash is valid
if (validated) {
// usually, you would do a HTTP request and use the parameter
var code = "<h1>" + validated[1] + "</h1>";
var element = document.getElementById("targetElement");
element.innerHTML = code;
} else {
// invalid hash, redirect to #home, without creating a new history entry
location.replace("#home");
}
// and set the new state
oldHash = newHash;
}
}
// periodically (every 50 ms) watch for modification in the hash part
setInterval(watchHash, 50);
HTML code:
Home
About Me
Contact
<div id="targetElement">
<!-- HTML will be inserted here -->
</div>

Categories