Two different versions of JQuery in the same HTML page - javascript

I have an HTML document where I have referenced jQuery version 1.2.2 in the header for thickbox and I have later referenced jQuery 1.7.1 just before the </body> tag which is for a picture slideshow.
The problem is that the thickbox won't work unless the reference for jQuery 1.7.1 is removed which then stops the slideshow from working.
I have googled around to find out about $ conflict but none of the suggested solutions worked.
The most common one I have seen and did tried is: var $j = jQuery.noConflict();
How can I resolve this?

<script src="http://code.jquery.com/jquery-1.2.2.min.js"></script>
<script type="text/javascript">
var jQ122 = jQuery.noConflict();
</script>
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
var jQ171 = jQuery.noConflict();
(function($) {
$(function() {
// here $ is jQuery 1.2.2
});
})(jQ122);
(function($) {
$(function() {
// here $ is jQuery 1.7.1
});
})(jQ171);
</script>

If the plug-ins are well-behaved, then this should work:
<script src="jquery-1.2.2.js"></script>
<script src="thickbox.js"></script>
<script src="jquery-1.7.1.js"></script>
<script src="slideshow.js"></script>
(Obviously those script names are made up.) Here's an example (source) (I used jQuery 1.4.2 and jQuery 1.7.1 because Google doesn't host 1.2.2).
The above works with well-behaved plug-ins because a well-behaved plug-in doesn't rely on the global $ at all, but rather uses the value of the jQuery global as of when it was loaded and grabs a reference to it in a closure, then uses that local reference throughout the plug-in's code, like this:
// Example plug-in setup
(function($) {
// ...Plug-in code using `$` here -- note it's a *local* `$`,
// not the global `$`, and not the global `jQuery`...
})(jQuery);
or
(function() {
var $ = jQuery;
// ...Plug-in code using `$` here -- note it's a *local* `$`,
// not the global `$`, and not the global `jQuery`...
})();
Both of those grab the global jQuery value as of when the plug-in is loaded and then use their local alias throughout.
If the plug-in wants to wait for the ready event, it can also do this:
jQuery(function($) {
// ...Plug-in code using `$` here -- note it's a *local* `$`,
// not the global `$`, and not the global `jQuery`...
});
...which uses the jQuery function passed into the ready handler.
Any of those three would work correctly (with thickbox seeing jQuery 1.2.2, and slideshow seeing jQuery 1.7.1) with the script load order listed above.
But the "if" in my opening sentence is a big "if". A lot of plug-ins are not written to be bullet-proof in this way.
The above notwithstanding, I would migrate away from any plug-in that requires jQuery 1.2.2 in order to work, and wherever possible (and it's almost always possible) avoid having to load two different versions of any library, including jQuery, in the same page.

I would not advise using two different versions of jQuery. There are some other alternatives to thickbox that works perfectly with the latest jQuery.

What you want to do is an extremely bad practice (you should indeed migrate all code to the same version) but it can theoretically be done...
You would need to make changes to the respective plugins anyways tho...
consider this code:
<script src="jquery-1.4.js"></script>
var jQuery14 = jQuery;
<script src="jquery-1.7.js"></script>
var jQuery17 = jQuery;
you would then change the code of your plugins at the point where jQuery is handed to the plugin, which would look similar to this:
(function( $ ){
// all your plugins code would be here
})( jQuery ); // replace "jQuery" with one of your respective jQuery14/jQuery17 versions/variables
Be advised.. this is veryveryvery messy to say the least!
write clean code or pay later! :)

Although you could use jQuery.noConflict(); to declare separate versions of jQuery at the same time.
I've often had some problems with IE8 with certain libraries when I do that.
So, an alternate solution would be to use an iframe to load a page within your current page.
Have a given version of jQuery on one page, and another on the second.
For example:
<iframe frameborder="0" width="700" height ="400" scrolling="no" seamless="seamless" src="your.html"></iframe>

Related

How to organise multiple portlets which require jQuery and jQuery extensions?

I am developing a few portlets for Liferay 6.2 and chose to use jQuery along with a number of extensions.
I seem to be getting problems where the extensions I need are attaching themselves to a jQuery instance which is not the one that I am using in the portlet. So when I come to use an extension it is not available.
My code looks something like this. The liferay-portlet.xml contains
<header-portlet-javascript>/js/jquery-1.12.2.min.js</header-portlet-javascript>
<header-portlet-javascript>/js/jquery-ui.min.js</header-portlet-javascript>
<header-portlet-javascript>/js/datepicker-de.js</header-portlet-javascript>
<header-portlet-javascript>/js/calendar.js</header-portlet-javascript>
In the JSP
<script type="text/javascript">
var $CAL;
jQuery.noConflict();
jQuery( document ).ready(function( $ ) {
$CAL = jQuery; // create my own jQuery handle
...
$CAL.datepicker.setDefaults($CAL.datepicker.regional['de']);
// $CAL.datepicker is NULL !
});
</script>
I'm not sure, but I think the datepicker function gets attached to a different jQuery instance. The debugger lists about 7 instances of jQuery and 3 instances of jQueryUI that different portlets are loading.
After some research, we tried to load all JS libraries in the theme but some portlets are loaded before the theme. Our current attempt is to load them in a 'hook'. That is still on-going.
At the moment we are creating all the portlets ourselves. It is possible that in the future we might want to use a 3rd party portlet so I'm wondering what the best approach is.
EDIT
The answer below and How to resolve two jquery conflict?
show how to avoid the conflict when multiple jQuerys are loaded. Is this best practice in Liferay portlet development? I assume that the are times when requiring different jQuery versions is unavoidable but is it normal for each portlet to simple load its' own copy of jQuery?
$CAL = jQueryis the issue. Define $CAL as variable referencing jQuery.noConflict()
Create a different alias instead of jQuery to use in the rest of the
script.
var j = jQuery.noConflict();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script type="text/javascript">
$CAL = jQuery.noConflict();
$CAL(document).ready(function() {
$CAL.datepicker.setDefaults($CAL.datepicker.regional['de']);
console.log("jQuery version ", $CAL().jquery);
$CAL("body").datepicker("dialog", "10/14/2016");
});
</script>

jQuery version conflict - load two versions same time

In my regular project setup we are using jQuery v1.6.2, but recently we have started to use Kendo UI plugin for charts; this plugin won't support the jQuery version v1.6.2, it works only with v1.7 or higher, so we are forced to load v1.7 also using noConflict.
Are there any side effects to my existing old code? Can we load and use two versions of jQuery at the same time?
Yes, you can do it. Using jQuery.noConflict() you can make multiple versions of jQuery coexist on the same page:
<script src='jquery-1.3.2.js'></script>
<script>
var jQ132 = jQuery.noConflict();
</script>
<script src='jquery-1.4.2.js'></script>
<script>
var jQ142 = jQuery.noConflict();
</script>
extracted from jQuery forums
Later, you just use jQ16 instead of $, e.g.:
<script>
jQ16.ready(function($) {
// inside here, $ refers to jQ16
$('#something').val(); // ...
});
</script>

Conflict between pages in Jquery easy tabs, trying to solve with jquery noconflict

I have an easy tabs page,with three different pages(TAB1,TAB2,TAB3).
Tab.php
Tab1|Tab2|Tab3
//Tab1 has an slider plugin(with Jquery UI)
//Tab2 has an autocomplete for select list
The conflict come from because two function wants to use jquery variable.
Two pages contains jquery plugins but with only jquery version(jquery-1.11.1.min.js)
The tabs only works properly(elements showing,jquery methods correctly running) when only one tabs is enabled(just commenting the link).
I use the jquery no conlict to try to solve this problem(before that there was conflict between the main tab page and the invidual page):
<script type="text/javascript" src="jquery-1.11.1.min.js"></script>
<script type="text/javascript">
var s = $.noConflict();
</script>
So on the sub page(tab1) i use like:
s(document).ready(function(){.....}
I also try to define a second shortcut(first i try to use the same 's' there too) :
<script type="text/javascript" src="jquery-1.11.1.min.js"></script>
<script type="text/javascript">
var j = $.noConflict();
var s = $.noConflict();
</script>
to use this at the Tab2 page.It was not a solution for me.Diseable Tab1 and using 'j' also works good.
One more importent thing is the firts downloaded page shown correctly each time,so i know the conflict is becuse of the jquery variable(overwrite it or something like this).
I try to find a solution by my self but i couldn't.Please help me
Update1:
As i note before i made a lot of research before that:
Jquery tabs conflicting with revolution slider
This question is very similar for my problem,but the difference i have more tabs,more conflict so i thought if i use more shortcut it will solve the issue.
Update2:
It is more interfering between the plugins than conflict.
using
var s = $.noConflict(true);
totally throw awey the full page,even the tabs does not want to work
First the tab.php load,it is using the jquery global variable,
than if i click on Tab1 it is also wants to use the global variable,
After if i click on Tab2 also need jquery variable
So bumm the interfering is ready
Update3:
After a lot of research,i found the problem is not with the noconflict.
The Tab2(upload.php) page is correctly rendered when i full reload the page.
s(document).ready(function(s) {//without the ready it does not rendered even after F5
s("#modell").select2(); });
I believe that you are trying to load jQuery with a different variable name. I would suggest that you use:
$.noConflict();
jQuery( document ).ready(function( blah ) {
//You can now use blah as the jquery method (e.g. blah("#button").click();)
});
I've made an example here: http://jsfiddle.net/me66st8w/. You can find out more about this in the official documentation here: http://api.jquery.com/jquery.noconflict/.

Using jQuery noConflict() with script.aculo.us

I have a site using a "widget" (from http://healcode.com) that includes the script.aculo.us JavaScript library. The problem is that the site I'm building is on WordPress, so there's the classic jQuery vs script.aculo.us conflict.
I know that I need to run jQuery in .noConflict() mode, but I must be getting the syntax wrong. When I assign the $ to jQuery .noConflict as follows, it still shuts down the script.aculo.us functions:
var $ = jQuery.noConflict();
$(document).ready(function () {
//#nav-main dropdown effects
$('#nav-main ul li').hoverIntent(function () {
$(this).find('.dropdown').stop(true,true).slideDown('900'); },
function(){
$(this).find('.dropdown').stop(true,true).slideUp('500');
});
}); // end document.ready
I know that I am assigning the $ to jQuery in .noConflict() mode, and I assume that script.aculo.us (which loads via a widget in the main body, therefore AFTER jQuery) is trying to re-assign the $ back to script.aculo.us.
How can I assign the $ to jQuery in a way that the later-loaded script.aculo.us library won't conflict? I've already tried the following without any success (the following code causes script.aculo.us to work, but jQuery to fail):
jQuery(document).ready(function () {
//#nav-main dropdown effects
jQuery('#nav-main ul li').hoverIntent(function () {
jQuery(this).find('.dropdown').stop(true,true).slideDown('900'); },
function(){
jQuery(this).find('.dropdown').stop(true,true).slideUp('500');
});
}); // end document.ready
EDIT
The debug console output for the above code is:
Uncaught TypeError: Object #<HTMLDocument> has no method 'ready' (anonymous function) so the document.ready fails because it's assigned to jQuery, which is somehow not loading properly...
EDIT 2
Both of the 2 (at the time of this update) answers posted below do nothing to address the issue I'm struggling with. Perhaps they are technically correct, but they do not address my issue.
This worked for me so that I can have jQuery and script.aculo.us/Prototype working well together. Credit goes to codeimpossible for this lifesaver!
Instead of:
jQuery(document).ready(function () {
// Code to run on DOM ready
}); // End document.ready
Try this:
( function($) {
// Code to run on DOM ready
} )( jQuery ); // End document.ready
I found the solution VERY surprising!
First of all, using the $j = jQuery.noConflict(); mode did not work.
Second, calling jQuery.noConflict(); at the head did not work.
The method that did work was this one: http://codeimpossible.com/2010/01/13/solving-document-ready-is-not-a-function-and-other-problems/
Oddly, the Coda Slider 2.0 plugin does not automatically do noConflict so it turned out that IN ADDITION to the problems listed above, I needed to wrap that plugin in .noConflict(); as well. Shout out the the author of the blog post, not sure why other noConflict(); calling methods didn't work, but I'm glad I found the post.
Assigning jQuery right back to $ doesn't do anything.
Either assign jQuery to a different variable:
var j$ = jQuery.noConflict();
Or don't assign it to anything:
jQuery.noConflict();
Try this:
<script src="url to jquery"></script>
<script type="javascript">jQuery.noConflict();</script>
<script src="url to scriptaculous"></script>

How to solve jQuery and mootoools conflict?

I use
<script type="text/javascript" src="jquery-1.2.2.pack.js"> </script>
to load jquery and then load an external script that contains these :
var jkpanel={
controltext: 'menu',
$mainpanel: null, contentdivheight: 0,
openclose:function($, speed){
this.$mainpanel.stop() //stop any animation
if (this.$mainpanel.attr('openstate')=='closed')
this.$mainpanel.animate({top: 0}, speed).attr({openstate: 'open'})
else
this.$mainpanel.animate({top: -this.contentdivheight+'px'}, speed).attr({openstate: 'closed'})
},
init:function(file, height, speed){
jQuery(document).ready(function($){
jkpanel.$mainpanel=$('<div id="dropdownpanel"><div class="contentdiv"></div><div class="control">'+jkpanel.controltext+'</div></div>').prependTo('body')
var $contentdiv=jkpanel.$mainpanel.find('.contentdiv')
var $controldiv=jkpanel.$mainpanel.find('.control').css({cursor: 'wait'})
$contentdiv.load(file, '', function($){
var heightattr=isNaN(parseInt(height))? 'auto' : parseInt(height)+'px'
$contentdiv.css({height: heightattr})
jkpanel.contentdivheight=parseInt($contentdiv.get(0).offsetHeight)
jkpanel.$mainpanel.css({top:-jkpanel.contentdivheight+'px', visibility:'visible'}).attr('openstate', 'closed')
$controldiv.css({cursor:'hand', cursor:'pointer'})
})
jkpanel.$mainpanel.click(function(){jkpanel.openclose($, speed)})
})
}
}
//Initialize script: jkpanel.init('path_to_content_file', 'height of content DIV in px', animation_duration)
jkpanel.init('1', '80px', 1000)
and also use a mootools plugin of course.
MY QUESTION IS THAT how should I use var $j = jQuery.noConflict(); in the above script to prevent conflicting
Wrap all the JavaScript that relies on jQuery in a closure to prevent namespace conflicts, like so:
// Start closure to prevent namespace conflicts
;(function($) {
// Whatever code you want that relies on $ as the jQuery object
// End closure
})(jQuery);
It looks weird, but the syntax is right (yes, the first line starts with a semicolon). This automatically substitutes jQuery for the $ object, which both jQuery and mootools make use of. Since you're using both, you should wrap all of your jQuery code in a closure like this (one for each .js file or script tag).
If the problem is just, you load MooTools, and then you load jQuery, and then MooTools doesn't work because jQuery has taken over the dollar function, then you probably just need code like this:
<script type="text/javascript" src="mootools.js"> </script>
<script type="text/javascript" src="jquery-1.2.2.pack.js"> </script>
<script type="text/javascript">
jQuery.noConflict();
</script>
That should get jQuery to relinquish $(). The code you have in your question already does the other handy thing, which is use the parameter to the ready event handler as a way to locally use a shorter name for the jQuery object.
I'd strongly recommend reading the jQuery page on working with other libraries and maybe the documentation for the noConflict() function.

Categories

Resources