jquery ajax html response change 1.3.2 vs 1.4.2 (aka where is my script tag?)
I've been using jquery 1.3.2 to pull snippets of html (including script) from a server. A typical response might be:
<div id="content"><div id="inner">...
<script type=...> alert("hello world");</scri开发者_开发技巧pt>
<p>Hello World</p>
</div></div>
I've been using the query .get function:
$.get($(this).attr("href"), function(response) {
$("#inner").replaceWith($("#inner", response));
});
And everything is fine and works as expected: the returned html snippets get loaded into the DOM and the scripts run.
When I use 1.4.2 however, I notice that the script tags have been removed and no longer run.
Stepping into the newer jquery codebase yields the lines of code (line 4498) :
ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
which seems to be the culprit 'removing' the script from its happy resting place as part of the selector process. But it doesn't help me in injecting exactly what i want into the DOM.
Any idea why jquery is doing this? More importantly, how can I go about fixing this so that my scripts run?
If you can change your server side code to return this (just remove the wrapper divs which are present anyway)
<script type="text/javascript">alert("hello world");</script>
<p>Hello World</p>
then you could use
$("#inner").load($(this).attr("href"));
Which doesn't seem to suffer from this problem.
Or if really just a snippet of this form (which is valid xml) is returned, you might also try specifying xml
as dataType
.
$.get($(this).attr("href"), null, function(response) {
$("#inner").replaceWith($("#inner", response));
}, "xml");
I don't know if everyone will agree but I would say the problem is in the structure of what you are doing.
Pulling javascript syntax out of database sounds like a really strange thing to do while you can simply have the in js files and call them to do their things when the page is ready.
everything is fine and works as expected: the returned html snippets get loaded into the DOM and the scripts run.
Possibly not in all browsers it didn't.
Loading <script>
s into the DOM via HTML (explicitly through a domManip
-based function, or as the outcome of a load()
) is something that's wonky and behaves differently cross-browser; it should be avoided.
jQuery attempts to put some workarounds in to make it better, which is part of what you're seeing there (it tries to extract <script>
elements from content and execute them manually), but it's not foolproof for all cases and you shouldn't rely on it. [Note that the same code is present in 1.3.2 (line 955), so this is nothing new.]
Best approach: keep your static code separate from your markup; don't pass scripts back in content for insertion into the DOM; when you need to add data or call a trigger post-insertion, do it in code passed back separately from the HTML (eg. as part of a JSON object).
The issue is not that using embedded scripts is wrong or inappropriate, but rather that jquery breaks up severly when upgrading from 1.3.2 to 1.4.2. I deem thinking this was unintentional from the jQuery developers. I hope this will be fixed in subsequent releases, as its makes jQuery (and jQuery-ui) terribly less appealing. Meanwhile, I'll advise to look into other alternatives, such as Mootools or Yahoo UI as a workaround for ajax-mode HTML parsing.
精彩评论