Side navigation
#975 closed bug (fixed)
Opened February 18, 2007 04:21AM UTC
Closed July 20, 2007 10:01PM UTC
Last modified March 15, 2012 04:28PM UTC
$().html().evalScripts() Eval's Scripts Twice in Firefox
Reported by: | aaron.heimlich@gmail | Owned by: | john |
---|---|---|---|
Priority: | major | Milestone: | 1.1.4 |
Component: | ajax | Version: | 1.1.3 |
Keywords: | script html double eval execute | Cc: | |
Blocked by: | Blocking: |
Description
Test page: http://aheimlich.freepgs.com/tests/jquery/ajax-load/
Firefox seems to eval scripts as soon as they are appended to the DOM tree, so my patch (see below) simply prevents evalScripts()
from running in Firefox, since the way it is most often used ends up making it redundant. Example:
jQuery("#target").html('<script type="text/javascript">alert("I come from the land of Ajax");</script>').evalScripts()
would cause "I come from the land of Ajax" to get alerted twice in Firefox, but only once in every other browser (and in those browsers, it would be the evalScripts()
call that would cause it). Code similar to this is used to inject remote HTML (which may contain <script> tags) into a web page.
I have only seen this occur in Firefox (though I have heard, but not been able to verify, one report of it happening in IE 6 and 7), so you should continue to use evalScripts()
as normal, as it is still necessary in other browsers.
Patch
Index: ajax.js =================================================================== --- ajax.js (revision 1365) +++ ajax.js (working copy) @@ -121,6 +121,11 @@ * @cat Ajax */ evalScripts: function() { + if(jQuery.browser.mozilla) { + // Firefox eval's scripts when they get added to the DOM tree, + // so this isn't necessary here + return this; + } return this.find("script").each(function(){ if ( this.src ) jQuery.getScript( this.src );
It should be trivial to include a switch for situations where you would ''want'' to run evalScripts()
in Firefox (though I can't think of any, since, if I understand correctly, the reason evalScripts()
exists is to evaluate the contents of <script> tags that have been recently added to the DOM, since most browsers won't do this on their own).
Attachments (1)
Change History (10)
Changed February 19, 2007 04:34AM UTC by comment:1
component: | ajax → core |
---|---|
keywords: | script load double eval execute → script html double eval execute |
priority: | major → minor |
summary: | $().load() Eval's Scripts Twice in Firefox → $().html().evalScripts() Eval's Scripts Twice in Firefox |
Changed February 22, 2007 04:45PM UTC by comment:2
Replying to [comment:1 brandon]:
However if you call .html().evalScripts() this bug still exists.
Which is what originally prompted me to post this issue (and what my patch is designed to fix)
Changed February 24, 2007 04:16AM UTC by comment:3
It seems a more appropriate fix would be to strip the scripts from the HTML before inserting it into the DOM. Then evalScripts should really just be a string method that evals scripts from a string of HTML. This would mean moving the current evalScripts method to the the jQuery namespace from the jQuery.fn namespace (much like jQuery.trim).
Also, is Firefox right to automatically run the scripts when appended to the DOM? Should the methods like .html(), .apppend(), etc automatically run the scripts for other browsers as well? It seems like this is usually the desired behavior. The clean method would then need to be able to strip and execute script nodes and script tags in an HTML string.
Changed March 24, 2007 06:17PM UTC by comment:5
milestone: | → 1.1.3 |
---|---|
need: | → Test Case |
priority: | minor → major |
Changed March 25, 2007 10:45AM UTC by comment:6
Added test in [1582]. Passes only in Opera.
Changed March 25, 2007 10:46AM UTC by comment:7
need: | Test Case → Patch |
---|
Changed July 04, 2007 06:04PM UTC by comment:8
I'm not sure if this is the same bug or if it's just related, but there is definitely an issue with Firefox loading javascript twice for scripts that are loaded via ajax.
In the example below, a section of the page is loaded dynamically via ajax, and it contains the following:
<input type="button" id="btntest" value="Test" />
<script type="text/javascript">
$(document).ready(function(){
$('#btntest').click(function(){
alert("HEY");
});
});
</script>
When you click the button, "HEY" is alerted twice! This seems to
happen whether or not it is enclosed within document.ready. If you put
the javascript inline then it only does it once, but I'd rather not do
that. The event should not be firing twice in Firefox. It works fine in IE7.
Changed July 20, 2007 09:48PM UTC by comment:9
component: | core → ajax |
---|---|
description: | Test page: http://aheimlich.freepgs.com/tests/jquery/ajax-load/\ \ Firefox seems to eval scripts as soon as they are appended to the DOM tree, so my patch (see below) simply prevents `evalScripts()` from running in Firefox, since the way it is most often used ends up making it redundant. Example:\ \ {{{\ jQuery("#target").html('<script type="text/javascript">alert("I come from the land of Ajax");</script>').evalScripts()\ }}}\ \ would cause "I come from the land of Ajax" to get alerted twice in Firefox, but only once in every other browser (and in those browsers, it would be the `evalScripts()` call that would cause it). Code similar to this is used to inject remote HTML (which may contain <script> tags) into a web page.\ \ I have only seen this occur in Firefox (though I have heard, but not been able to verify, one report of it happening in IE 6 and 7), so you should continue to use `evalScripts()` as normal, as it is still necessary in other browsers.\ \ == Patch ==\ {{{\ Index: ajax.js\ ===================================================================\ --- ajax.js (revision 1365)\ +++ ajax.js (working copy)\ @@ -121,6 +121,11 @@\ * @cat Ajax\ */\ evalScripts: function() {\ + if(jQuery.browser.mozilla) {\ + // Firefox eval's scripts when they get added to the DOM tree,\ + // so this isn't necessary here\ + return this;\ + }\ return this.find("script").each(function(){\ if ( this.src )\ jQuery.getScript( this.src );\ }}}\ \ It should be trivial to include a switch for situations where you would ''want'' to run `evalScripts()` in Firefox (though I can't think of any, since, if I understand correctly, the reason `evalScripts()` exists is to evaluate the contents of <script> tags that have been recently added to the DOM, since most browsers won't do this on their own). → Test page: http://aheimlich.freepgs.com/tests/jquery/ajax-load/ \ \ Firefox seems to eval scripts as soon as they are appended to the DOM tree, so my patch (see below) simply prevents `evalScripts()` from running in Firefox, since the way it is most often used ends up making it redundant. Example: \ \ {{{ \ jQuery("#target").html('<script type="text/javascript">alert("I come from the land of Ajax");</script>').evalScripts() \ }}} \ \ would cause "I come from the land of Ajax" to get alerted twice in Firefox, but only once in every other browser (and in those browsers, it would be the `evalScripts()` call that would cause it). Code similar to this is used to inject remote HTML (which may contain <script> tags) into a web page. \ \ I have only seen this occur in Firefox (though I have heard, but not been able to verify, one report of it happening in IE 6 and 7), so you should continue to use `evalScripts()` as normal, as it is still necessary in other browsers. \ \ == Patch == \ {{{ \ Index: ajax.js \ =================================================================== \ --- ajax.js (revision 1365) \ +++ ajax.js (working copy) \ @@ -121,6 +121,11 @@ \ * @cat Ajax \ */ \ evalScripts: function() { \ + if(jQuery.browser.mozilla) { \ + // Firefox eval's scripts when they get added to the DOM tree, \ + // so this isn't necessary here \ + return this; \ + } \ return this.find("script").each(function(){ \ if ( this.src ) \ jQuery.getScript( this.src ); \ }}} \ \ It should be trivial to include a switch for situations where you would ''want'' to run `evalScripts()` in Firefox (though I can't think of any, since, if I understand correctly, the reason `evalScripts()` exists is to evaluate the contents of <script> tags that have been recently added to the DOM, since most browsers won't do this on their own). |
milestone: | 1.1.3 → 1.1.4 |
owner: | → john |
version: | 1.1 → 1.1.3 |
Changed July 20, 2007 10:01PM UTC by comment:10
resolution: | → fixed |
---|---|
status: | new → closed |
Fixed in SVN rev [2428].
The .load() method has been fixed in Rev 1364.
However if you call .html().evalScripts() this bug still exists.