I have the problem that I want to load a Javascript on a website from another website and use jQuery there. But it seems jQuery is never available.
I tried all the things in this post: Test if jquery is loaded not using the document ready event.
Is it maybe a security cross site issue?
Here is the page:
Japanese cities
jQuery is loaded here in line 29
<script src="/cache/template/gzip.php?jquery.min-3eab6f02.js" type="text/javascript"></script>
The script is loaded in line 343
<script type="text/javaScript" src="http://www.factfish.com/api/js/japanese_cities.js"></script>
To narrow it down I just used an empty $ajax function
(function() {
if (jQuery) {
$.ajax({});
}
})();
I always get the error
TypeError: $.ajax is not a function
Any ideas?
Thank you
Bernhard
In your page there's
<script src="/cache/template/gzip.php?jquery-noconflict-4baa84c1.js" type="text/javascript"></script>
which does this:
jQuery.noConflict();
This means you
Relinquish jQuery's control of the $ variable
I.e. $ is no longer associated with jQuery, and you must explicitly use jQuery instead.
See this: https://api.jquery.com/jquery.noconflict/
This should work:
(function() {
if (jQuery) {
jQuery.ajax({});
}
})();
Another way to do this:
(function( $ ) {
$(function() {
// More code using $ as alias to jQuery
$.ajax({});
});
})(jQuery);
As pointed out by #dekkard, you have effectively erased the $ shortcut alias for jQuery.
As an alternative to the IIFE's shown by #dekkard, There is also a shortcut DOM ready that combines document.ready with a locally scoped $
e.g.
jQuery(function($){
// Your DOM ready code - using a locally scoped $
});
"Half the code, twice the flavour!" :)
Related
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>
This is a common idiom:
<html>
<head>
<script>
(function($) {
$(document).ready(function(){
// some jQuery/JavaScript in here
}
})(jQuery);
</script>
</head>
....
So we using a JavaScript immediate function which executes some jQuery. Now usually, it is advised to put JavaScript down the end of the page to allow progressive rendering. My questions are:
If you are using JavaScript in the head, what difference does it make if you make the function execute immediately?
Will ${document).ready(...) block excution, or does it happen asynchronously?
It ensures that, inside the IIFE, $ === jQuery. Before this script excert, you could have other libraries included (such as Prototype), which have their own definitions of $.
<script src="/jquery.js"></script>
<script src="/Prototype.js"></script>
<script>
$(document).ready(function () { // error, $ is something to do with prototye
});
</script>
<script>
(function ($) {
$(document).ready(function () { // this works fine
});
}(jQuery));
</script>
It is not the execution of $(document).ready() that blocks execution, it's the downloading of remote scripts.
<script src="/jquery.js"></script> <!-- page is blocked whilst jQuery is downloaded -->
<script> // This doesn't block the page load
$(document).ready(function () {
});
</script>
Additionally, I wouldn't call that a common idiom. It's common when creating a plugin, but not for wrapping $(document).ready() in. The following was created for that, and has the same affect;
jQuery(document).ready(function ($) { // "jQuery is always passed as first param, alias with `$`
// Inside here, $ === jQuery
});
IIRC, it will be fired when the document is done loading and not prevent any other execution.
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>
I am using a 3rd party script to add a zoom function to images on a page. This works quite well with static, but not with dynamic content.
Static version, works:
$(document).ready(function(){
$('#gallery_main_img').addpowerzoom();
})
Dynamic version, doesn't work:
$(document).ready(function(){
$('#gallery_main_img').load(OnGalleryImageChanged);
})
function OnGalleryImageChanged() {
$('#gallery_main_img').addpowerzoom();
}
The addpowerzoom function is created with this code in the PowerZoom script, which is referenced in the <head> of my page:
$.fn.addpowerzoom=function(options){
// function content here
}
When entering the event handler, Firebug gives me this error message:
$("#gallery_main_img").addpowerzoom is not a function.
So it seems to be a scope problem. My question is:
How do I access the addpowerzoom() function from within my event handler?
If you check that 3rd party script's source, the first thing you'll notice it do is set jQuery in noConflict mode, with the code jQuery.noConflict() and it doesn't assign it to a variable either, meaning the $ isn't reserved for jQuery anymore.
As you mentioned that the first case is working, I am presuming that you have the ready statement before you include the 3rd party script, because otherwise that wouldn't work either.
You could either change your code to this (replacing $ with jQuery):
jQuery(document).ready(function(){
jQuery('#gallery_main_img').load(OnGalleryImageChanged);
})
function OnGalleryImageChanged() {
jQuery('#gallery_main_img').addpowerzoom();
}
example: http://jsfiddle.net/niklasvh/8Vjnu/
or wrap the code inside of a:
(function($) {
$(function() {
// more code using $ as alias to jQuery
});
})(jQuery);
or perhaps remove the noConflict from the 3rd party script altogether (something that the author should have never put in there in the first place, unless they assume that everyone who use the script wants to remove jQuery from $).
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.