Skip to main content

Bug Tracker

Side navigation

#10066 closed bug (invalid)

Opened August 16, 2011 09:43PM UTC

Closed August 17, 2011 01:19AM UTC

Last modified August 18, 2011 05:33PM UTC

Double referencing jQuery deletes all assigned plugins.

Reported by: adsood Owned by:
Priority: low Milestone: None
Component: misc Version: 1.5.1
Keywords: Cc:
Blocked by: Blocking:
Description

Scenario:

  • A web page loads external HTML page and displays it in the Dialog using jQuery UI library.

What happens:

  • When a formatted (HTML) page is loaded into existing document (using .load() function) browser build DOM and loads any scripts if they are referenced on the loaded page.

if both the host page and the loaded page refer to jQuery library, the jQuery script will be executed twice.

As jQuery script executes it re-initializes $ and $.prototype, which removes all existing plug-ins.

The host page stops working.

Example:

The following example is simplified version of the issue (jquery explicitly loaded twice):


<html>
<head>
    <title>jQuery double reference</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <script type="text/javascript">
        $.fn.test = function(method) {
		alert('test');
	}
    </script>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <script type="text/javascript">
	$(function() {
		$('body').test();
	});
    </script>
</head>

<body>
</body>
</html> 

No alert has been displayed and an error reported in the console:

"Uncaught TypeError: Object [object Object] has no method 'test'"

or

"$("body").test is not a function"

...

Solution:

At the beginning of jQuery script add verification if jQuery has been loaded already:

...
if (typeof jQuery === 'undefined')

(function( window, undefined ) {

// Use the correct document accordingly with window argument (sandbox)
var document = window.document;
var jQuery = (function() {

// Define a local copy of jQuery
var jQuery = function( selector, context ) {
...

Similar approach has been utilized by jQueryUI.

tested in:

Chrome - 5.0.375.9

Chrome - 13.0.782.112 m

Firefox - 3.6.18

Firefox - 5.0

IE - 9.0.8112.16421

Attachments (0)
Change History (4)

Changed August 17, 2011 01:19AM UTC by rwaldron comment:1

component: unfiledmisc
priority: undecidedlow
resolution: → invalid
status: newclosed

Use $.noConflict().

Also, this will happen in any programming language that allows for the declaration and assignment of variables.

Changed August 18, 2011 12:18AM UTC by adsood comment:2

_comment0: There is not conflict here with any other libraries. \ It is not the matter of using $ sign or not using. \ The problem is that jQuery (and its alias - $) get completely wiped out with and replaced with the new copy. "jQuery" variable get reinitialized as well. \ \ We develop our own plug-in and follow all the recommendations from jQuery documentation. However, the plug-in get removed from jQuery prototype. \ $.noConflict() will not help here. \ \ I do not fully understand the reference to other programming languages and its relevance to the problem. If, however, we look at other JavaScript libraries that can suffer from the same issue, then we can see that they use simple verification against double-loading case. \ \ An example is jQueryUI library: \ \ {{{ \ $.ui = $.ui || {}; \ if ( $.ui.version ) { \ return; \ } \ }}} \ \ This is a valid issue. Please open the ticket. \ 1313626946809585

There is no conflict here with any other libraries.

It is not a matter of using $ sign or not using.

The problem is that jQuery (and its alias - $) get completely wiped out and replaced with the new copy. "jQuery" variable get re-initialized as well.

We develop our own plug-in and follow all the recommendations from jQuery documentation. However, the plug-in get removed from jQuery prototype.

$.noConflict() will not help here.

I do not fully understand the reference to other programming languages and its relevance to the problem. If, however, we look at other JavaScript libraries that can suffer from the same issue, then we can see that they use simple verification against double-loading case.

An example is jQueryUI library:

$.ui = $.ui || {};
if ( $.ui.version ) {
	return;
}

This is a valid issue. Please open the ticket.

Changed August 18, 2011 02:53PM UTC by ajpiano comment:3

The fact that jQuery UI does not allow multiple instantiations of the library is not germane to this discussion. jQuery has historically allowed you to have as many copies of jQuery on the page as you like/need, and loading jQuery again will destroy the existing jQuery, unless you've aliased to somewhere else beforehand, perhaps using noConflict.

I certainly understand why this issue is annoying - it was the first big "jQuery Bug" I had a number of years ago when I was getting started that drove me into the community in the first place. WHERE ARE MY PLUGINS GOING? Turned out I was accidentally AJAX'ing whole pages and thus reloading and clobbering jQuery when I didn't even intend to.

However, I am now of the mind that it is the developer's responsibility to ensure that their assets are loading properly and reliably. Because of the various use cases for loading multiple copies of jQuery on a page, we simply cannot block multiple instantiations with the technique you've described here and thus will not reopen this ticket.

Changed August 18, 2011 05:33PM UTC by adsood comment:4

@ajpiano:

I understand your ground in general.

The statement "Because of the various use cases for loading multiple copies of jQuery on a page, we simply cannot block multiple instantiations" intrigues me.

Could you provide a one or two real-life (or practically useful) examples of using "loading multiple copies of jQuery on a page" technique?

Thanks.