Wordpress ships jQuery in safe mode, this is very awesome, but a 3rd party script that I must use uses the $ alias, so there's a way of alias $ to jQuery only for that script ? (can't edit the script since it's 3rd party)
wrap the initialisation of the plugin in an IIFE
(function($){
$('.some').pluginUsingDollarAsJQuery();
})(jQuery)
As per the help pages for plugin authorship:
The $ variable is very popular among JavaScript libraries, and if you're using another library with jQuery, you will have to make jQuery not use the $ with jQuery.noConflict(). However, this will break our plugin since it is written with the assumption that $ is an alias to the jQuery function. To work well with other plugins, and still use the jQuery $ alias, we need to put all of our code inside of an Immediately Invoked Function Expression, and then pass the function jQuery, and name the parameter
Which basically boils down to the fact that whoever has written the plugin you're using has not done it right.
Writing a plugin like this:
$.fn.doSomething = function(){
// whatever
}
Will make it not compatible with anyone using jQuery in noConflict mode. It should be wrapped in an IIFE like this:
(function($){
$.fn.doSomething = function(){
// whatever
}
})(jQuery)
If your plugin is the former style, ditch it.
Jamiec's answer is the clean solution which should be used if you have access to the code, but in case you do not have access to it, there is a dirty solution.
You can reassign $ to jQuery just before the script is loaded. So when the script is initializing, $ === jQuery.
To do it when the script is inline in the DOM, just open a script tag for the reassignment before :
<script>$=jQuery;</script>
<script src="external_script"></script>
If you load dynamically the script (ex : jQuery.getScript), you can reassign just before calling the async function :
window.$ = jQuery;
jQuery.getScript('external_source');
WARNING : this method can break your script if window.$ was used elsewhere. It may also not work if the script is loaded asynchronous if, meanwhile, another script reassign $ to something else.
Related
I have been using jQuery for quite a few years now, and after I include the jQuery scripts in whatever site I am working on, I would always use the $ for jQuery objects. For example:
$('#my_selector').click(function(){...
I had built a website a few years ago in Joomla 1.6 with over 200 pages and jQuery used in almost all of them, all with the $. Now I am rebuilding the site in Joomla 3.3.0. The funny thing is, now sometimes the $ just doesn't work when identifying jQuery objects, but when I use jQuery it works. For example. the above code example would have to be changed to this:
jQuery('#my_selector').click(function(){...
And that works. And the final strangest thing is that on one page, it seems like the $ works for some of the jQuery but not all. The error that I see is this one:
TypeError: undefined is not a function
Seems like the problem occurs mostly on the functions that run after load complete circumstances. Anyway I am just wondering if people out there know why the $ would stop working with identifying the jQuery functions and objects.
Thanks!
You are most probably using a conflicting library, meaning: another script/library that declares (and thus overrides) the variable $. Wrap all your code in a closure, and you should be good:
(function($) {
$('#my_selector').doStuff();
})(jQuery)
Or, if it needs to be executed after document ready:
jQuery(document).ready(function($) {
$('#my_selector').doStuff();
});
Joomla 3.x is moving progressively to jQuery and replacing all MooTools dependencies along the way.
The default state is to load jQuery in noConflict() mode, but depending on features used on any given page by extensions (templates,plug-ins, components or modules) MooTools may also be loaded.
That means that on some pages, jQuery is defined and not $ and on other pages both are defined, obviously this will result in the issues you are seeing.
Add to that most third-party extensions from the 1.6 era (you have been upgrading to the 2.5.x line along the way right?) just ignored what-ever was going on and loaded whatever they needed (potentially blowing away other libraries) you generally will have to sort out all the conflicts first.
The only guaranteed way to use jQuery is by using the jQuery prefix.
You can read about using JavaScript frameworks with Joomla here, amongst other things it gives you future proof mechanism built-in to Joomla for loading jQuery.
To load jQuery, use: JHtml::_('jquery.framework');
To load the jQuery UI core call: JHtml::_('jquery.ui');
As has been mentioned you can wrap your JavaScript in a closure, in fact this is what the core com_banners does in /media/cbanner.js
var jQuery;
(function ($) {
$(document).ready(function () {
$('#jform_type').on('change', function (a, params) {
var v = typeof(params) !== 'object' ? $('#jform_type').val() : params.selected;
switch (v) {
case '0':
// Image
$('#image, #url').show();
$('#custom').hide();
break;
case '1':
// Custom
$('#image, #url').hide();
$('#custom').show();
break;
}
});
});
})(jQuery);
Are you or joomla using mootools or any other library with the $?
This would mean there is a conflict and the right way to solve it, is by using jQuery instead of $.
I don't think this can be done, though I know requirejs can do something similar, and I was wondering if this might be possible outside of require.
I'm writing a piece of SaaS JavaScript code that will most likely need jQuery to run cross browser. Some sites have it, some don't, but I don't want to stick jQuery on the window object if they aren't using it. Though I could individually create alternatives for everything I use jQuery for... I was wondering if there is a way I can load jQuery only for use inside my closure. Is this possible?
When you load the standard release of jQuery, by default jQuery assigns itself to the global names jQuery and $. If you load your version of jQuery before your closure file within the page, then within your closure do
var $ = jQuery.noConflict(true);
It will undo whatever modifications your version of jQuery did to the global object.
It is worth noting, however, that this produces a race condition. If any events or timeouts fire between the time that your jQuery file loads and your closure calls jQuery.noConflict(true) they will accidentally use the version of jQuery that you loaded.
An alternative is to edit the jQuery file that you are using to include a call to jQuery.noConflict(true) at the bottom of the jQuery file. You can assign the result to an arbitrary name that no one else would ever think to use, like "abcRandomNumberHere". Then you can retrieve your instance of jQuery from that global name within your closure assigning it to a local variable named jQuery and/or $ and delete the global reference at that time.
// Your jQuery file on your server
// ...
// End of file:
someRandomGlobalName = jQuery.noConflict(true);
// The file that contains your closure:
(function() {
var $, jQuery;
$ = jQuery = someRandomGlobalName;
delete window.someRandomGlobalName;
// Your code that uses jQuery here
} ());
This is a rough approximation of what RequireJS does to keep jQuery out of the global namespace. Recent versions of jQuery have built-in code that detects the existence of a script loader like RequireJS and rather than assigning to global names jQuery passes a reference to itself into RequireJS and leaves the global object untouched. That way RequireJS contains the reference to jQuery internally, but the global.requirejs variable is modified instead.
Creating your own non-conflicting global name for your jQuery version and your closure to "rendezvous" on is analogous to RequireJS' functionality. The name RequireJS uses is the "global name": requirejs.s.contexts._.jQuery (not exactly, but something like this).
Call jQuery.noConflict(true) and it will re-assign $ and jQuery to wherever it was.
Then, you can pass the reference returned by the above expression into your closure.
(function(jQuery) {
})(jQuery.noConflict(true));
Yes, calling jQuery.noConflict(true) will completely remove anything that jquery added from the global namespace reverting it back to what it was previously allowing for conflicting libraries and/or multiple versions of jQuery.
<script src="jquery.min.js"></script>
<script>
(function($){
$("el").doSomething();
})(jQuery.noConflict(true));
</script>
I am in the process of installing the asset pipeline into an older rails app. I am getting some really strange results though. I can see that the page is rendering all of the css and the jquery that is in the app/assets directory but its having a hard time interacting with the html.
For instance if i inspect the page and in the console call $("html").html(); to try grab all the html it returns TypeError: Cannot call method 'html' of null same when trying to grab any element that is being rendered? but the page is there. if i call jQuery it will return fine. so its not like it jQuery isnt there.
$ is just a shorthand way of writing jQuery. If the latter works but the former doesn't, then another script in your pipeline is probably conflicting with jQuery and trying to use the $ symbol for something else.
Are you using any other plugins or libraries that might be trying to use $? Or have you accidentally overwritten it yourself by writing $ = (something) anywhere? Without more information it's hard to know where the problem is exactly.
If all else fails you can just stick to using jQuery() for all your calls. In your external script file you could also circumvent this by passing the jQuery object to a wrapper function, e.g.:
(function ($) {
$('div').append('You can use $ here without having to worry about conflict.');
}(jQuery))
I have 2 js on a single page. In one of the js I am doing var jQuery = $.noConflict(true); and after that using all the jQuery methods using jQuery object, like jQuery("#div").hide();
In another js, I am using the traditional $ variable & accessing the jQuery methods as $("#div").hide();
When on a page I use either of the 2 js', things work fine. However, when I include both, the $ in the second js seems to be overwritten by jQuery. for example, in js 2 I can no longer do $("#div").hide() but if I use jQuery instead of $, it works fine - jQuery("#div").hide();!
Why am I experimenting this is because the first div will be distributed to different websites as a plugin, and the second js could be the Jquery written by that website developer.
Please help me figure out where am I going wrong..
Thanks.
You're using noConflict, which releases jQuery's hold on $. Doesn't matter if it's in separate scripts, since it's the same global environment.
In the script where you want to use $, define that variable inside your .ready() handler.
jQuery(function($) {
$('foo').bar();
});
The easiest way to solve this is to use a pattern that plugin authors employ.
(function($) {
// Use $ safely within the function
})(jQuery); // Passes in jQuery object
This is function is created and invoked immediately, and at the same time allows you to pass a variable into the scope of the function. Using this, you can carry on referring to $ in your code and not worry about overwriting it or conflicting.
The jQuery documentation advises this pattern
Files do not have scope, you dereferenced $ with noConflict for your entire page. Anything
I am creating a web widget to be posted on other websites. In the widget it will call jQuery and I dont want the jQuery to conflict with other JavaScript libraries that the website may have installed. When I load the jQuery I would like to call jQuery like this:
JQuery_MYSite('id').find('selector');
I found out if I do this then $ will not be able to be used even if the other website uses $.
When the widget loads it find out if jQuery is loaded. If so, then it will use the $ to call jQuery. But I know $ is not unique to just jQuery - other javascript libraries use it. So how can I use my own jQuery prefix with without interfering with the website owners prefix.
In the widget it will call jQuery and I dont want the jQuery to
conflict with other JavaScript libraries that the website may have
installed.
I don't think you can achieve this, because jQuery.noConflict() must be called after the other scripts have been loaded. So, if there is no way for you to know about the other scripts, then you won't have a way to avoid the conflicting.
When the widget loads it find out if jQuery is loaded. If so, then it
will use the $ to call jQuery. But I know $ is not unique to just
jQuery - other javascript libraries use it. So how can I use my own
jQuery prefix with without interfering with the website owners prefix.
Wrap your widget code with an auto-executing anonymous function:
(function($){
// your widget code here
// $ will always be jQuery
})(jQuery);
var myJquery = jQuery.noConflict();
then if you want to get fancy:
(function($){
$(".whatever").doSomeStuff();
})(myJquery);
use noConflict
<script type="text/javascript">
$.noConflict();
jQuery(document).ready(function($) {
// Code that uses jQuery's $ can follow here.
});
// Code that uses other library's $ can follow here.
</script>
Check out jQuery.noConflict().
look at noConflict
$.noConflict();
(function($){
// $ is jQuery here
})(jQuery);