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.
Related
At my website, I am loading jQuery asynchronously.
In order to do that, I must run jQuery functions only after it is really loaded.
I've tried two pure JS ways:
<script src="js/jquery-2.2.2.min.js" async></script>
<script>
window.addEventListener('load', function() {
//stuff
}, true);
</script>
And
window.onload = function() {
//stuff
}
But even so I still get Uncaught TypeError: $(...) is not a function at...
How do I fire jQuery functions after the lib is fully loaded?
You need to add the script only after jQuery library is loaded using script tag.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
// your code should be here
alert(typeof jQuery)
</script>
The document ready handler is using to execute the code only after DOM elements are loaded.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
console.log('Outside document ready handler ' + $('.test').length)
$(document).ready(function() {
console.log('Inside document ready handler ' + $('.test').length)
});
</script>
<div class="test"></div>
UPDATE 1: You can use defer if script is in a file, refer following question: jquery loaded async and ready function not working
UPDATE 2: Or you can bind load event handler to the script tag using addEventListener method.
<script async id="script" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
document.getElementById('script')
.addEventListener('load', function() {
alert(typeof jQuery)
});
</script>
FYI : I don't know why you are doing this, for optimizing the speed of content load it's always better to move the script tags at the end of body which helps to load content first.
You could do something like this:
function checkVariable(){
if ( window.jQuery){
Do your jquery stuff here
}
else{
window.setTimeout("checkVariable();",100);
}
}
checkVariable();
Apologies for the formatting...stuck on my phone right now.
I did not see this method listed, so I thought I would demonstrate using the JavaScript HTML DOM EventListener.
Example #1 Using the jQuery.ready() Method:
<p id="test-jquery">jQuery Not Loaded</p>
<script>
$(document).ready(function() {
var elem = $('#test-jquery');
elem.text('jQuery Is Loaded');
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
This method will not work since jQuery has yet to be loaded.
Running the above example will output:
ERROR: {
"message": "ReferenceError: $ is not defined",
"filename": "https://stacksnippets.net/js",
"lineno": 13,
"colno": 3
}
Example #2 Using the addEventListener() Method:
<p id="test-jquery">jQuery Not Loaded</p>
<script>
window.addEventListener('DOMContentLoaded', function() {
var elem = $('#test-jquery');
elem.text('jQuery Is Loaded');
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
This method will work since we are listening for the Window DOMContentLoaded event.
From Mozilla:
The original target for this event is the Document that has loaded.
You can listen for this event on the Window interface to handle it in
the capture or bubbling phases. For full details on this event please
see the page on the Document: DOMContentLoaded event.
A different event, load, should be used only to detect a fully-loaded
page. It is a common mistake to use load where DOMContentLoaded would
be more appropriate.
You can use this:
<script>
document.addEventListener('readystatechange', event => {
if (event.target.readyState === "complete") {
// window loaded, external resources are loaded too...
jQuery(function($) {
// your code here: $("a").css(...)
}
}
});
</script>
I used it when inline jQuery script did not work on safari (Mac and iOS) and this solved the problem.
Use document.ready or load the library in the header. That should work.. Be sure to load in the right folder or in the right link. If you are usying a link to load jquery then be sure to have an internet connection
I cannot wrap my head around this issue and the vast offer of information I found on the net:
On my project the JQuery is loaded with "defer". This I cannot change due to project standards.
<script defer src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js'></script>
Now I need to add some small functions to a page (currently inline):
With this setup the browser will try to execute the inline scrip before jQuery loads => "Uncaught ReferenceError: $ is not defined"
<body>
...
...
<script>
$("#city").change(function() {...some stuff...};
$("#doctor").change(function() {...some stuff...};
</script>
</body>
Whats the smart way to resolve this?
Wrap it inside window.onload, so the script will only be executed when everything is fully loaded.
Try this example:
window.onload = function () {
$("#city").click(function() {
alert('city');
});
$("#doctor").click(function() {
alert('doctor');
});
}
<script defer src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js'></script>
<button id="city">City</button>
<button id="doctor">Doctor</button>
Explanation about window.onload from MDN:
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links, and sub-frames have finished loading.
https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onload
For more idiomatic (in jquery) way, use the code below. it's the same with window.onload.
$(document).ready(function() {
// put code here
});
Another alternative, use $(function() { }).
$(function() {
// put code here
})
Pros: With this approach, you don't have to wait for the 'load' event to trigger.. this should execute as soon as jQuery has finished loading.
var initInterval = setInterval(function(){
if(window.jQuery) {
clearInterval(initInterval);
init(); // where init is the entry point for your code execution
}
}, 20);
function init(){
$('#example').text('Ahoy!');
}
<script defer src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js'></script>
<div id="example">Hi</div>
This way you can add multiple functions to window.load:
window.addEventListener("load",function(event) {
$("#city").click(function() {
alert('city');
});
},false);
window.addEventListener("load",function(){
$("#doctor").click(function() {
alert('doctor');
});
},false);
In order to optimize the load of my document, I use to load jQuery async like that
<script async type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
Then I call a script using jQuery :
<script type="text/javascript">
jQuery(document).ready(function() {
App.init();
OwlCarousel.initOwlCarousel();
FancyBox.initFancybox();
StyleSwitcher.initStyleSwitcher();
});
</script>
It returns me that jquery is not defined.
I don't know what should I use, I though that .readyfunction would wait until all document is loaded before calling it.
The same for Bootstrap library, It tells me that jQuery is not defined.
I've tried to ask the script to be loaded at the end, but it still does not work properly.
Since jquery script is loaded asynchronously, jquery is not loaded on the moment your script is executing. So you need to wait for it to load by subscribing on load event like this:
<script async id="jquery" type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
Then listen for a load event on this element
<script type="text/javascript">
document.getElementById('jquery').addEventListener('load', function () {
App.init();
OwlCarousel.initOwlCarousel();
FancyBox.initFancybox();
StyleSwitcher.initStyleSwitcher();
});
</script>
But I don't know why someone wants to do things like this.
To optimize page loading speed it is better to put all you javascript at the end of the body, so content will be loaded first, and scripts won't delay page rendering event if it's synchronously loaded.
Edit: I agree with comment and consider previous paragraph not the best way of loading jQuery to the page
Question Script Tag - async & defer has good answer to your problem.
In a nutshell you cannot load jQuery, or other library, asyncronously when some other script depends on it without some additional asyncronous handling for executing the scripts depending on the library.
That is my solution:
<script async type="text/javascript" src="path_to_jquery" id="jquery_script_tag">
</script>
<script>
if ( !('jQuery' in window) )
{
window.jQueryQueue = [];
//define temporary jQuery function
window.jQuery = function(){
//just save function parameters to queue
jQueryQueue.push( arguments );
}
document.getElementById('jquery_script_tag').addEventListener('load', function(){
//call jQuery with parameters saved in queue, after it loaded
for ( var i in jQueryQueue )
jQuery.apply( document, jQueryQueue[i] );
});
}
</script>
This code defines a temporary jQuery function if it is yet not defined. The function saves all jQuery function calls to queue while the real jQuery has not yet loaded (instead of calling undefined jQuery function). And when jQuery has loaded, it calls the jQuery functions in the queue with the same parameters as called before.
jQuery, and all components that depend on jQuery (including Bootstrap), depend on hooking the DOMContentLoaded event to set up events.
This means jQuery (and anything that uses $(function() {...})) must be downloaded before DOMContentLoaded fires, or it never hooks up its events.
In turn, that means <script async ... will be unreliable, breaking whenever jQuery takes longer to download than the page content does.
Unfortunately <script defer ... doesn't work either thanks to jQuery trying to fire as soon as the document.readyState === "interactive".
You can load content and then load jQuery by putting the <script> at the end of the <body> but this will result in a noticeable pause between the page appearing and any of the jQuery firing - users won't be able to click on anything, visual components won't appear, and so on.
This way works just fine:
<script charset="utf-8" type="text/javascript">
var intervalID = window.setInterval(function(){
if(window.jQuery){
clearInterval(intervalID);
console.log('Loaded');
/* Your code here */
}
},1000);
</script>
You Used Async Loading When You Try Access Jquery It Not Loaded By Browser You Can Access Jquery After Page Loading Is Complete .
Load Jquery Normally To Fix Your Problem .
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!" :)
I want to call another function before body, but how?
The system shows me the error undefined function myx
I only can add code after body.
<script type="text/javascript">
jQuery(function($){
function myx() {
alert("omg");
};
});
</script>
</head>
<body>
<script>
jQuery(document).ready(function($){
$("mytest").click(function(){
myx();
});
});
</script>
Check
That function is out of scope. You need to define the function outside the jQuery callback.
<script type="text/javascript">
function myx() {
alert("omg");
};
</script>
</head>
<body>
<script>
jQuery(document).ready(function(){
$("#mytest").click(function(){
myx();
});
});
</script>
Check
Use external JavaScript, so it's cached into the Browser Memory, so when your Client visits again it will load faster. Then look at this:
// wrapper is same as $(document).ready() with no-conflict
jQuery(function($){
// should be defined once everything has loaded
function myx(){
// never use alert except to test
alert('OMG!');
}
// passing a function name like a var is the same as Anonymous function
$('#mytest').click(myx);
});
// Ignoring outer wrapper to save indenting - indent everything further
The important thing is that myx should be defined after everything has loaded.
You don't have to, but it's a best practice to use external JavaScript and put the <script> tags in the <head>, setting both <script type='text/javascript' src='yourUrl.js'></script> to be W3C Compliant. Additionally, technologically the document.body may not be available to some older Browsers if your <script> tags are defined in the <body>, as HTML must be defined before JavaScript is able to get it, which is why you use the Anonymous function inside of jQuery() (same as $(document).ready() or the JavaScript onload Event). Then you get the HTML with JavaScript because those Elements are available onload.