I am developing an ASP.NET server control that uses jQuery for some client side logic. I have embedded the jQuery file as a resource inside the control.
I don't want to restrict the application using the control to that specific version of jQuery and I want to keep using the version of jQuery that I have embedded.
I know about the noconflict method but the problem that i see with that is that i have no control over the order of the script tags on the page.
If the user's version of jQuery is included before mine than I'll end up overriding it before I can call noconflict.
Please help
You can do this with noConflict(true)
:
var myJQuery = jQuery.noConflict(true);
The true
parameter tells jQuery to release the jQuery
symbol in addition to the $
symbol. Just add this to the end of the jQuery.js file you're embedding in the control.
The jQuery script is smart about conflicts. The first thing it does is grab whatever the current value of both $
and jQuery
are and squirrel them away so it can restore them later if you ask it to. So if your script is loaded first, neither $
nor jQuery
will be defined and the new one can have them. If your script is loaded second, it restores the earlier $
and jQuery
.
Example:
Let's assume you're using the latest (v1.5.1), but the page author is using the older 1.4.4. Effectively, by tacking var jq151 = jQuery.noConflict(true);
on the end of the 1.5.1 file, you're doing this:
<script src='jquery-1.5.1.min.js'></script>
<script>var jq151 = jQuery.noConflict(true);</script>
...except it'd all be in one script tag. So two possibilities:
1) They go first:
<script src='jquery-1.4.4.min.js'></script>
<script src='jquery-1.5.1.min.js'></script>
<script>var jq151 = jQuery.noConflict(true);</script>
Live example
2) You go first:
<script src='jquery-1.5.1.min.js'></script>
<script>var jq151 = jQuery.noConflict(true);</script>
<script src='jquery-1.4.4.min.js'></script>
Live example
Either way, both jQuery
and $
end up pointing to their 1.4.4 version, and jq151
ends up pointing to your 1.5.1 version.
Perhaps slightly off-topic, but for anyone thinking this is a bit magical, it's actually really easy. :-) Here's a script that will redefine foo
, but restore the previous definition if you ask it to:
// The script
(function() {
var globalObject = this, // Or just use `window` on browsers
oldfoo,
ourfoo;
oldfoo = globalObject.foo;
ourfoo = globalObject.foo = {
version: "new",
restorePrevious: restorePrevious
};
function restorePrevious() {
globalObject.foo = oldfoo;
return ourfoo;
}
})();
Example with foo
defined before the above
Example with foo
defined after the above (if you're wondering why this works despite var foo
being after the script, here's some reading on read up on poor, misunderstood var
)
About plug-ins: You asked below about plug-ins. Plug-ins register themselves by assigning their features to properties on jQuery.fn
and (in some cases) jQuery
, like so:
jQuery.fn.makeFoo = function() {
};
With the above, you can access a makeFoo
function on jQuery instances (e.g., $('foo').makeFoo();
). A well-written plug-in will ensure that it plays nicely with both noConflict()
and noConflict(true)
by using this structure:
(function($) {
$.fn.makeFoo = function() {
$(this).addClass("foo");
};
})(jQuery);
...or one like it. (With the above, we'd never use jQuery
to refer to jQuery within the function body. If we wanted to, we could add var jQuery = $;
at the top.)
That defines an anonymous function and immediately calls it, passing in the current global value for jQuery
. It receives that as a $
argument, and so within the function the symbol $
will always be the jQuery
instance that it passed into itself. It can freely use $
knowing that it refers the the version of jQuery on which it's registered.
An only somewhat well-written plug-in may assume that jQuery
will always be the same (e.g., only plays nicely with noConflict()
and not with noConflict(true)
). You can fix those, though. If you run into one, make a copy of it and put
(function($) {
var jQuery = $;
...at the top and
})(jQuery);
...at the bottom. 99% of the time, that will make it behave.
If you want to use plug-ins with your embedded jQuery instance, your best bet is to include them in your customized file. So the file contents become:
- The jQuery script
- (plug-in script)
- (plug-in script)
- ...
- Your
var jq151 = jQuery.noConflict(true);
Here's a nice solution: Don't use jQuery. At least - not at first. Use javascript to wait until all scripts have loaded, store the value of "$", and then inject jQuery in via script tag, and restore the previous value of "$".