2

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");</script>

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

Joel
  • 19,175
  • 2
  • 63
  • 83
cmroanirgo
  • 7,297
  • 4
  • 32
  • 38

4 Answers4

1

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");
jitter
  • 53,475
  • 11
  • 111
  • 124
0

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.

makeitmorehuman
  • 11,287
  • 3
  • 52
  • 76
  • I can see many use cases for such a scenario, but the OP didn't say the content is coming from a db, just that it is mixed HTML and JS. – Joel Mar 24 '10 at 00:01
0

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

bobince
  • 528,062
  • 107
  • 651
  • 834
  • Considering it runs in IE, FF, Chrome and Safari, I think it's safe to say that it does work. I missed the lines in 1.3.2. Regardless, to then serve tightly coupled script/html snippets in two ajax requests just because jQuery has decided to 'Big Brother' me is ludicrous IMHO. – cmroanirgo Mar 24 '10 at 02:20
  • 1
    You don't need two requests, you can have one request returning a JSON object that holds an HTML property and a code string property. See http://stackoverflow.com/questions/1661224/stop-ie-from-loading-dynamically-included-script-twice for some of the background to why `innerHTML`-inserted ` – bobince Mar 24 '10 at 11:03
0

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.