Another jQuery version in function closure - javascript

I'm developing some script, which developers will include on their pages.
I need jQuery in this script. And if page already have jQuery, don't override them. I want to use my jQuery(in my anonymous function). And i want to page use jQuery whitch used before me(not my jQuery).
Is it possible?
Thanks.

Use jQuery.noConflict. Here’s an example:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>window.$jq164 = jQuery.noConflict(true);</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>window.$jq171 = jQuery.noConflict(true);</script>
Now you can use $jq164 and $jq171 separately.

Related

How to resolve JQuery Conflicts between 3 or more dependent versions of JQuery using .noConflict?

I've found many other similar questions but this particular scenario is somewhat unique to the more typical ones to which the prior questions are applicable.
My understanding and the normal approach I use to resolve conflicts between 2 versions of JQuery are as follows in this example:
<script type="text/javascript" src="../Static/jquery-1.3.2.min.js" ></script>
<script type="text/javascript" src="/Scripts/jquery-ui 1.12.1.custom/jquery.js"></script>
<script type="text/javascript">
var JQuery_1_12_1 = $.noConflict(true);
$JQuery_1_12_1(document).ready(function () {
// Code dependent on JQuery 1.12.1 can safely execute here without
// conflicting with version 1.3.2
});
</script>
<script type="text/javascript">
// Code executed within this block will use 1.3.2
</script>
Alternatively, I could have duplicated the approach implemented to define the noConflict variable for 1.12.1 for 1.3.2 and the result would have been the same.
The problem I'm having difficulty in resolving is that I'm confronted with a situation I previously haven't had to deal with where there are linked library dependencies that need to be combined together in a noConflict manner.
Here is the current situation:
<script type="text/javascript" src="../Static/jquery-1.3.2.min.js" ></script>
<script type="text/javascript" src="/Scripts/jquery-ui-1.12.1.custom/jquery-ui.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui 1.12.1.custom/jquery.js"></script>
<script type="text/javascript">
var JQuery_1_12_1 = $.noConflict(true);
$JQuery_1_12_1(document).ready(function () {
// Code dependent on JQuery 1.12.1 can safely execute here without
// conflicting with version 1.3.2 but do to the lack of the dependent version this code will always break
});
</script>
<script type="text/javascript">
// Code executed within this block will use 1.3.2
</script>
As you can note, there is an inter-dependency between jquery-ui.js and jquery.js and due to this inter-dependency the $JQuery_1_12_1 variable cannot be applicable to both.
Alternatively, creating a separate noConflict variable for the jquery-ui.js library would require it to be placed within the context of a separate script tag which would essentially break the dependency and the code won't function correctly.
How can this problem be resolved?
I have also tried using the same versions of one of the JQuery libraries to alleviate the conflicts but they each have a unique set of features that don't crossover. So only one version will work per required application within the code.
First: Don't use multiple versions of jQuery. It bloats and complicates your page. Use an up-to-date version of jQuery and, if you have plugins that don't work with that up-to-date version, update them so they do (and ideally send a pull-request back to the plugin's repo if it has one), or use something that's actively maintained instead.
Now, if for some reason you can't do that:
Any half-decent jQuery plugin uses the jQuery variable's value as of when the plugin is loaded, by doing something like this:
(function($) {
// Plugin code
})(jQuery);
If you load a different version of jQuery afterward, the plugin still uses the earlier one because it captured the value of jQuery as of when it loaded.
So load your plugins for a given jQuery version immediately after loading that version of jQuery.
Then: Do the same for your own code.
<script src="../Static/jquery-1.3.2.min.js" ></script>
<script src="../plugin/that/needs/version/132.js"></script>
<script src="../your/code/that/needs/version/132.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui 1.12.1.custom/jquery.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui-1.12.1.custom/jquery-ui.js"></script>
<script src="../your/code/that/needs/what/jQueryUI/is/using.js"></script>
...where your script code does the same thing a well-behaved plugin does:
(function($) {
// Use $ here
})(jQuery);
If you have code that (shudders) needs to use both versions of jQuery, capture each version in a variable:
<script src="../Static/jquery-1.3.2.min.js" ></script>
<script src="../plugin/that/needs/version/132.js"></script>
<script>
var jQuery_v132 = jQuery;
</script>
<script src="../your/code/that/needs/version/132.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui 1.12.1.custom/jquery.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui-1.12.1.custom/jquery-ui.js"></script>
<script>
var jQuery_whatever = jQuery;
</script>
<script src="../your/code/that/needs/what/jQueryUI/is/using.js"></script>
<script src="../your/code/using/both.js"></script>
...where your code using both uses jQuery_v132 or jQuery_whatever as appropriate.
(I've used "whatever" because I have no idea what version of jQuery your jquery-ui 1.12.1.custom/jquery.js file is, but it's unlikely to be jQuery 1.12.1.)

using two versions of jquery in the same page returns 'Undefined is not a function'

I tried using jQuery_1_9_1 and jQuery_1_4_2 in the same page
But when trying to open popups in my page I am getting
Undefined type Err 'Undefined is not a function' at this point
jQuery_1_9_1.fn.track=function(){
jQuery_1_9_1(this).each(function(){
return new Track(jQuery_1_9_1(this));
Also I am using Mootools in my page .
Could anyone pls help why I am getting this error.
Edit
<script type='text/javascript' src='../assets/js/jquery-1.4.2.min.js'></script>
<script type='text/javascript'> var jq = jQuery.noConflict(); </script>
I have given 1.4.2 in my template file and
<script type='text/javascript' src='../assets/js/jquery-1.9.1.min.js'>
<script type="text/javascript"> var jQuery_1_9_1 = jQuery.noConflict(true); </script>
in one of the commonly used JSP
First of all, you DO NOT NEED multiple versions of JQuery on a single page to achieve the desired functionality.
Secondly, since you are using Mootools and JQuery, best would be to use the following alternatives instead of the default $ in JQuery:
Using the jQuery instance directly
Using var jQ = jQuery.noConflict();
Also, it would be best for applications like this to use Asynchronous Module Definition - something like RequireJS to ensure you load only the JS files which are required for specific functionality.

Force AngularJS to use specific version of jQuery while using multiple versions of jQuery at once

I inherited the project where several version of jQuery are loaded into the page in noConflict mode. Application is huge, tests are missing and it seems every former devloper did not have "cohones" big enough to remove previous library. So the result is that $ refers to jquery version 1.4.2.
Is there any way/trick to tell angular wich version of jQuery should be used? Something like
angular.jq = j182
I know I can do it like
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="xxx/scripts/angular.js"></script>
<script>j182 = jQuery.noConflict();</script>
but then I have kind of "hidden dependency" which I would like to avoid.
You're right that $.noConflict() allows you to play with 2 versions of jQuery at once (which should be avoided unless REALLY necessary).
To make your angular module use the version you want, you can use ng-jq="whateverYouCallIt" where whateverYouCallIt is variable in window. Example:
<script type="text/javascript" src="/js/jquery-1.9.0.min.js"></script>
<script type="text/javascript">window.j190 = jQuery.noConflict();</script>
<script type="text/javascript" src="/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
console.log('globally available jQuery: ' + jQuery.fn.jquery);
console.log('j190: ' + window.j190.fn.jquery);
</script>
...
<div ng-app='myApp' ng-jq="j190" ng-controller='MyController' id="myAngularApp">
Just be careful, because if you need to access $scope from somewhere else, you will have to obtain it via the same jQuery that has been specified in ng-jq:
var myAnguarAppScope = window.j190('#myAngularApp').scope();
BTW, the above console.log calls output:
globally available jQuery: 1.7.2
j190: 1.9.0

How do you implement the jQuery noConflict() method correctly?

I can't get the noConflict() method to work properly. I've been searching online for hours and can't seem to get a solid answer. Here's what I have in my header...
<script type="text/javascript" src="js/mootools.js"></script>
<script type="text/javascript" src="js/slimbox.js"></script>
<script type="text/javascript" src="js/jquery.js"></script><!-- jQuery script -->
<script type="text/javascript" src="js/page_scroll.js"></script><!-- JavaScript -->
<script src="js/jquery.easing.1.3.js" type="text/javascript"></script><!-- jQuery easing plug-in -->
<script type="text/javascript">
var $j = jQuery.noConflict();
// Use jQuery via $j(...)
$j(document).ready(function(){
$j("div").hide();
});
// Use Mootools with $(...), etc.
$('someid').hide();
</script>
There's no other jQuery or JavaScript within my HTML (just what I have externally), so "placing anything that uses the $ variable in the noConlict method" is not an option.
Essentially what I'm trying to do is have slimbox and easing page scroll (for my navigation) to work together. The problem is of course one works when the other is removed and vice versa. Also, when I use the noConflict() method I get slimbox to work and not pagescroll, but when I remove the noConflict() method I get pagescroll to work and not slimbox. So apperently noConflict is doing something, I just don't know what that is or how to go about it.
If anyone can help me out, I'd appreciate it. Thanks.
when using other js libs that leverage the $ alias,
I have found reliable results by using
$.noConflict();
jQuery(document).ready(function($) {
// your jQuery code here i.e.
// jQuery('some-selector-expression').somefunction();
});
// prototype or mootools code that uses the $ alias works fine here
So are you saying it does not work when you declare $j? You can define your own alternate names (e.g. jq, $J, awesomeQuery - anything you want). Try calling it something w/o the $
Wrap it in an anonymous function:
(function($){
$(document).ready(function() {
// function here...
});
})(jQuery);
Seeing the exact code might help.

Using JQuery and Prototype in the same page

Several of my pages use both JQuery and Protoype. Since I upgraded to version 1.3 of JQuery this appears to be causing problems, because both libraries define a function named '$'.
JQuery provides a function noConflict() which relinquishes control of $ to other libraries that may be using it. So it seems like I need to go through all my pages that look like this:
<head>
<script type="text/javascript" src="/obp/js/prototype.js"></script>
<script type="text/javascript" src="/obp/js/jquery.js"></script>
</head>
and change them to look like this:
<head>
<script type="text/javascript" src="/obp/js/prototype.js"></script>
<script type="text/javascript" src="/obp/js/jquery.js"></script>
<script type="text/javascript">
jQuery.noConflict();
var $j = jQuery;
</script>
</head>
I should then be able to use '$' for Prototype and '$j' (or 'jQuery') for JQuery. I'm not entirely happy about duplicating these 2 lines of code in every relevant page, and expect that at some point somebody is likely to forget to add them to a new page. I'd prefer to be able to do the following
Create a file jquery-noconflict.js which "includes" jquery.js and the 2 lines of code shown above
Import jquery-noconflict.js (instead of jquery.js) in all my JSP/HTML pages
However, I'm not sure if it's possible to include one JS file in another, in the manner I've described? Of course an alternate solution is simply to add the 2 lines of code above to jquery.js directly, but if I do that I'll need to remember to do it every time I upgrade JQuery.
Currently you can do something like this:
<head>
<script type="text/javascript" src="/obp/js/prototype.js"></script>
<script type="text/javascript" src="/obp/js/jquery.js"></script>
<script type="text/javascript">
var $j = jQuery.noConflict();
</script>
</head>
Then, use jQuery as $j() and Prototype's $().
It would seem that the most simple answer would be to bite the bullet, and include your noConflict lines. Of course if your pages aren't using a shared header, that solution might not be the best.
This solution worked fine:
jQuery.noConflict();
var $j = jQuery;
Now use $j in place of $ for your jQuery code, like:
$j(document).ready(function() {
$j('#div_id').innerfade({
// some stuff
});
});
I went through this for a while. It is very annoying and in the end I decided to weed out all of my old Prototype stuff and replace it with jQuery. I do like the way Prototype handles some Ajax tasks but it wasn't worth the trade off of maintaining all of the no conflict stuff.
Just as a note to others that stumble upon this. The solutions are described here (mentioning prototype specifically):
http://docs.jquery.com/Using_jQuery_with_Other_Libraries
Could you not just include the jQuery = noConflict() code in the jquery.js source file? Why would it need to be defined that way?
Your jquery-noconflict.js should look like this (be sure that all is in one line):
document.write("<script type=\"text/javascript\" src=\"/obp/js/jquery.js\"></script><script type=\"text/javascript\">jQuery.noConflict();var $j = jQuery;</script>");
... and than your include (as you already pointed out) should look like this:
<head>
<script type="text/javascript" src="/obp/js/prototype.js"></script>
<script type="text/javascript" src="/obp/js/jquery-noconflict.js"></script>
</head>
This solution solves all your requirements I think.
<script>
document.write(unescape('%3Cscript type="text/javascript" src="/obp/js/jquery.js"%3E%3C/script%3E'));
</script>
<script>
jQuery.noConflict();
var $j = jQuery;
</script>
or
var scripty = document.createElement('script');
scripty.href="/obp/js/jquery.js";
document.getElementsByTagName('head')[0].appendChild(scripty);
jQuery.noConflict();
var $j = jQuery;
EDIT:
I tried out this suggestion but the last 2 lines produce the error
jQuery is not defined
You could call jquery first and then set
var $j = jQuery;
prototype will take control of $ in this case.
Or, you could just refer to jQuery by using the full jQuery function name (jQuery).
Use Prototype below jQuery like this:
<script type="text/javascript" src="news/jquery-1.2.3.pack.js"></script>
<script type="text/javascript" src="news/jquery.easynews.js"></script>
<script type="text/javascript" src="lb/js/prototype.js"></script>
<script type="text/javascript" src="lb/js/scriptaculous.js?load=effects"></script>
<script type="text/javascript" src="lb/js/lightbox.js"></script>
<link href="lb/css/lightbox.css" rel="stylesheet" type="text/css" />
in this case the jQuery function will create a problem, so you can use this to solve the problem:
<script type="text/javascript">
jQuery.noConflict();
var JQ = jQuery;//rename $ function
</script>
If I were you, I'd drop my no conflict code into a JavaScript include file like you opined about above, and then figure out some process where I'd be setting these things I need to include in all my pages in one central place. If you are working with straight HTML files and you don't have any kind of templating/scripting capability server-side for what gets included in a document, there's always the possibility of doing a Server-Side Include.
Either way, the pain you'll experience updating each of your pages this time will come back again when you need to update your analytics code or the site footer.
You need to load it in your public/javascript/application.js
jQuery.noConflict();
var $j = jQuery;
This is also a good article that may be helpful.
JQuery & Prototype working together

Categories