#746 closed bug (fixed)
$("#feeds").load("feeds.html") Call to .evalScripts() fails in Internet Explorer
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | major | Milestone: | 1.1a |
Component: | ajax | Version: | 1.1a |
Keywords: | load ajax | Cc: | |
Blocked by: | Blocking: |
Description (last modified by )
$("#feeds").load("feeds.html")
Call to .evalScripts() fails in Internet Explorer
jQuery.fn.extend for load: makes a call to jQuery.ajax(...) and on completion does a self.html(res.responseText) which eventually does a elem[fix[name]] = value and that is why it fails to process the scripts in Internet Explorer. The "innerHTML" attribute (also "text" attribute) for IE (tested/verified for IE 6.0) strips out <script> tag elements from the HTML. This is the test code that I used for my IE testing.
var script = "<script language="JavaScript" type="text/JavaScript">alert('im really running');</script>"; var oVDiv =document.getElementById("oDiv1"); oVDiv["innerHTML"] = script; // fails
Suggested fix would be to pass res.responseText to evalScripts: function() {
Change History (8)
comment:1 Changed 16 years ago by
Description: | modified (diff) |
---|---|
Milestone: | → 1.1 |
Priority: | minor → major |
Version: | → 1.1 |
comment:2 Changed 16 years ago by
Here's a modified version of the unit test from the form plugin:
test("load doc with scripts", function() { stop(); expect(3); $('#test').load('doc-with-scripts.html', function() { ok( $('#test').text().match("Lorem ipsum"), "target updated"); ok( typeof unitTestVariable1 != 'undefined', 'first script block executed'); ok( typeof unitTestVariable2 != 'undefined', 'second script block executed'); start(); }); });
The doc-with-scripts.html file looks like this:
<div> <script type="text/javascript"> // set global var var unitTestVariable1 = true; </script> Lorem ipsum dolor sit amet... <script type="text/javascript"> // set another global var var unitTestVariable2 = true; </script> </div>
The basic idea is to assert that both script blocks are executed AND the target of the load is updated.
comment:3 Changed 16 years ago by
This is the test from the testsuite:
test("load(String, Object, Function) - check scripts", function() { expect(7); stop(); testFoo = undefined; var verifyEvaluation = function() { ok( foobar == "bar", 'Check if script src was evaluated after load' ); ok( $('#foo').html() == 'foo', 'Check if script evaluation has modified DOM'); ok( $('#ap').html() == 'bar', 'Check if script evaluation has modified DOM'); start(); }; $('#first').load('data/test.html', function() { ok( $('#first').html().match(/^html text/), 'Check content after loading html' ); ok( testFoo == "foo", 'Check if script was evaluated after load' ); setTimeout(verifyEvaluation, 600); }); });
test.html:
html text<br/> <script type="text/javascript"> testFoo = "foo"; $('#foo').html('foo'); ok( true, "test.html executed" ); </script> <script src="data/test.js"></script> blabla
That works, so what are we missing?
comment:4 Changed 16 years ago by
Interesting. That works for me in IE6 & 7, although it's bugger to test through IE's caching. We should probably rework ajaxTest.js to append the current time to the URL. Is the setTimeout necessary?
comment:5 Changed 16 years ago by
The testsuite now has a url function that appends both timestamp and a random number to urls, no matte whether they already have a query string or not. That makes testing in both FF and IE much easier.
The timeout is necessary to check if test.js is properly evaluated. That requires another requests that we don't control, so we can't use a callback.
I'll check what happens if the html file contains only a script element and nothing else.
comment:6 Changed 16 years ago by
Ok, got it. IE strips the script tag when there is nothing else in the file. Even a single character in front of the script tag fixes the problem.
If anyone comes up with a nice workaround, fine, otherwise I just add a note to load() warning about this issue. If there is nothing else then the script tag, it's easy to strip that, too, and use $.getScript().
comment:7 Changed 16 years ago by
Looks like it strips the script if it is the very first subelement. For example,
<div> <script type="text/javascript"> alert('hello'); </script> </div>
does not alert. But this does:
<div> blah <script type="text/javascript"> alert('hello'); </script>
Nice work, Jörn. Looks like this is just a documentation issue. Cool.
comment:8 Changed 16 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
I added a note to load() about this problem. Just put a character in front of your script or use $.getScript() to avoid it.
Thanks for the report, that helps a lot. The issue occured before, but we failed to find the source of the problem.
The solution is a bit more complicated, because we have to insert the HTML into the DOM first before we can use any selectors. On the other hand, if we parse the HTML by hand and evaluate any scripts, we have to prevent that they are executed again later.