The execJS() I posted some time ago have some problems (and it, yes, was just a modify to the AHAH version). I didn’t really realized what exactly it is, but I found a simple (?) solution. The problem, as far as I can understand, is that eval() doesn’t always execute the code. So here it is the workaround: look for <script> tags, take its content and create a new element into the <head> with createElement/appendChild. In this way we should also be more standard-compliant than before:
function execJS(node)
{
var bSaf = (navigator.userAgent.indexOf('Safari') != -1);
var bOpera = (navigator.userAgent.indexOf('Opera') != -1);
var bMoz = (navigator.appName == 'Netscape');
if (!node) return;
/* IE wants it uppercase */
var st = node.getElementsByTagName('SCRIPT');
var strExec;
for(var i=0;i<st.length; i++)
{
if (bSaf) {
strExec = st[i].innerHTML;
st[i].innerHTML = "";
} else if (bOpera) {
strExec = st[i].text;
st[i].text = "";
} else if (bMoz) {
strExec = st[i].textContent;
st[i].textContent = "";
} else {
strExec = st[i].text;
st[i].text = "";
}
try {
var x = document.createElement("script");
x.type = "text/javascript";
/* In IE we must use .text! */
if ((bSaf) || (bOpera) || (bMoz))
x.innerHTML = strExec;
else x.text = strExec;
document.getElementsByTagName("head")[0].appendChild(x);
} catch(e) {
alert(e);
}
}
};
I tested it only under firefox, but it should work on other browsers too. If it doesn’t, let me know.
Update (October 1st, 2006): now it works under Internet Explorer too (if you want to inject some text in a script element in IE you can’t use .innerHTML, but you have to use .text!)
is there anyway to execute javascript that is loaded this way
script type=”text/javascript” src=”something.js”
instead of
script type=”text/javascript”
*all scripts here* /scripts
with this execJS function?
Not exactly, you should modify the execJS() in order to look for src attributes too and then pass the values to a function like this:
function load_ext_script(url)
{
var x = document.createElement(“script”);
x.src = url;
x.type = “text/javascript”;
document.getElementsByTagName(“head”)[0].appendChild(x);
}
I didn’t tested, but it should work.
Doesn’t work in IE.
IE doesn’t like .InnerHtml for the script object
:(
Oh, found a solution.
Use .text for IE!!!!
You mean using “x.text” instead of “x.innerHTML” in the try block? (I have to reformat this post, the transition from blogspot to wordpress indented incorrectly the code)
The code doesnt work in IE. Can anyone who gets it working in IE, pls post the changes made.
Thanks
I updated the script, now it should work under IE too… lemme know if something doesn’t work
From the entry:
} else if (bMoz) {
strExec = st[i].textContent;
st[i].textContent; // !!!
} else {
Note that st[i].textContent is missing the assignment.
} else if (bMoz) {
strExec = st[i].textContent;
st[i].textContent = “”;
} else {
Thanks for the code.
Uh, that’s what happens when you write code at 4 AM :) Corrected now…
var node = document.getElementById(node);
/*
little correction or else you get tihis error
node.getElementsByTagName is not a function
*/
if (!node) return;
/* IE wants it uppercase */
var st = node.getElementsByTagName(‘SCRIPT’);
Easier solution?
function execJS(node) {
if (!node) return;
var st = node.getElementsByTagName(‘SCRIPT’);
for(var i=0;i
“The problem, as far as I can understand, is that eval() doesn’t always execute the code.”
Can a collision of variable names be the problem?
var st = [
“for(var i=0; i<3; i++) alert(i);”,
“alert(‘I do not get executed’)”
];
for(var i=0;i<st.length; i++) {
eval(st[i]);
}
It seems you solved your problem by creating a new ‘script’ element. But just out of curiosity, do you get the problem you get with the eval approach if you replace eval with the next function?
function saferEval(__code__) {
eval(__code__);
}
I didn’t tried, but I believe that it won’t work (and it’s not a collision of variable names). The problem, as I realized some time after, is that the browser does NOT allow script executions loaded within the innerHTML method due to security reasons.
Thanks, works well! (In FireFox anyway, and I hope IE too… will let you know if not)
Just like andycjw I’m trying to use this script to load external *.js-files. But I didn’t manage to solve this with the code you posted above. Could you explain it further or maybe contact me by e-mail? Thanks in advance! Like your script
Neat script! Can I see some basic examples of this? I’m trying to insert a div (with innerHTML) with script tags in it that contains a function that loads in an swf. The SWFObject to be more exact http://blog.deconcept.com/swfobject/. Is that possible you think?
Cheers
Mike
hi,
I actually got this working… works ok in Safari and FF, but doesn’t seem to work in IE. Any suggestions?
http://catfish.businesscatalyst.com/CatalogueRetrieve.aspx?CatalogueID=8269&ProductID=132786
Cheers
mike
Mike…I’m also trying to get swfobject to work ie IE. But I didn’t succeed yet. Did you?
Cheers
‘The other’ Mike ;)
Hi Kratoruis,
Thanks for a wonderful script. However, could you help with how src=”something.js” can be managed?
BTW, the script is not working in IE. I tried alert(strExec) after:
} else {
strExec = st[i].text;
but while it enters the loop (I checked), it prints an empty string.
Okay, it works in IE. But there is a weird problem - the innerHTML cannot start with . I put some other HTML before that, and put the script later. Cheers!
I guess something got snipped out in my earlier comment due to being a tag - it should be, “the innerHTML cannot start with <SCRIPT>
uhm, I never noticed this behavior… Could you try if something like x.innerHTML = “<span></span>” + strExec; works?
This rocks. Works fairly well.
Followup to comment 2 regarding how to deal with src = url javascript files:
Downside: if you’re refreshing the innerHTML, you might be appending innerHTML src’d javascript files to the document head multiple times, leading to possible memory issues. You’ll want to check to see if you’ve already loaded a file via this method.
Caught that using the DOM inspector while watching the page refresh.
Hi.
Thanks for the post. I found it after a few seconds of simple googling after I experienced this problem for a work related issue. The thing is, what exactly is the “node” variable? In other words, is there an example you can give as to how to run it? I have a DIV tag that I’d like to run it on and I am unsure if this is exactly what I want to do. Of course, I haven’t experimented with it yet, but maybe I’ve answered my own question. Either way, could you provide an example? Keep up the good work!
Ok, I got it to work in Firefox, but still no IE. I know it says “it doesn’t like innerHTML!!!” but what do we need to change then? The function itself provided by this nice blog page or the actual javascript code where the DIV’s and SPAN’s are, etc, that have statements that change the innerHTML of them?
Ok, the problem with IE not working isn’t the .text or .innerHTML confusion. It is the fact that: var st = node.getElementsByTagName(‘script’); doesn’t behave the same in Firefox as it does in IE. Everytime I get here in IE, it returns an array with st.length being 0 everytime. So in other words, the for loop is never even executed. Even trying to set DIV or SPAN or whatever your node is with .text = ‘blah’ instead of .innerHTML makes no difference.
Ok, upon further investigation of my lead, someone on IRC was kind enough to explain to me the correct workaround to fix this annoying IE issue:
15:00:04 @makk | yeah, this is a known issue in IE
15:00:08 @makk | there is a trick to get around it
15:00:14 @makk | but i don’t recommend it
15:00:32 @makk | all you have to do is put some non-whitespace before the script tag
15:00:42 @makk | and then you should be able to grab the element
15:01:24 @makk | for example: div.innerHTML = ’ …’;