Do I have to use document ready for jQuery? - javascript

I have a script that I want to use, however, I don't know if I require to put document ready.
$(window).scroll(function(){
$(".hero-h1").css("opacity", 1 - $(window).scrollTop() / 250);
});

If position and run your script so that the elements it depends on already exist at the time it runs, no.
This is essentially the same question as whether someone needs to use
window.addEventListener('DOMContentLoaded', () => {
// all of the code
});
If, at the time your script runs, you try to select an element that isn't always present regardless - like a particular <div> on the page - for example
$('.mybutton').on('click', () => {
// ...
Then at the time that the above line runs, you need to make sure that .mybutton exists on the page.
This can be accomplished in a few ways. One of these ways is by wrapping the whole script in .ready (or, as is usually preferred nowadays, just a plain function):
$(() => {
$('.mybutton').on('click', () => {
// ...
Another way it can be accomplished is by putting your script after all the elements that it depends on in the HTML markup - for example
// lots of HTML code
<button class="mybutton">click</button>
<script src="myscript.js"><script>
</body>
If you put your script at the end of the body, all elements from the static page markup will exist in the DOM by then.
A third way is to give your script the defer attribute.
<script defer src="myscript.js"><script>
This will ensure that all static elements are loaded before the script runs.
For this particular case of yours, if all you do is add a scroll handler to the window, then there aren't any elements to wait for in order to attach the handler, so you may not need to use any of the approaches above.

Related

How to bind event Jquery to page?

I have Jquery function that executes AJAX query to server.
How can I call this after load page in the specified url page? May I bind this to element HTML, I mean:
<div id="graph" onload="function()"></div>
jQuery handles the HTML file with a variable called document.
Document has two popular event states
load when the page has been loaded
ready when the page has been loaded and all other decorations to the HTML have been applied.
jQuery provides hooks for these states.
To run javascript code after each of the events listed above, you have to put the function within the appropriate event scope.
For loading, this would be…
$(document).load(function() {
// javascript code you want to execute
})
After the page has been ready, but not yet rendered, you can apply some other javascript code using
$(document).ready(function() {
// javascript code you want to execute
})
One way using jQuery:
$(document).ready( function() {
//do whatever you need, you can check if some element exists and then, call your function
if($("#graph").length > 0)
callfunction();
});
No jQuery, only vanilla js:
window.onload = function() {
if(document.getElementById("graph"))
callfunction();
}

What javascript should put inside $(document).ready(function()?

Does $(document).ready(function() { means all javascript file has been downloaded so any js init or func should work?
so it is a good practise to always put js inside $(document).ready(function() { ?
$(document).ready is part of the page lifecycle and runs after all of the resources have been loaded for the page (HTML, CSS and JS files).
You should be functions in here that you need to run when the page first loads, so generally initialization of plugins, first run functions and attaching events to elements.
Any other functions that can run after the page has loaded can be defined outside of this scope.
Note that if you are dynamically inserting DOM elements, any events attached to that type or class (for example) will not be attached to them without re-attaching, or using .on and attaching to the document itself.
Use ready() to make a function available after the document is loaded:
for eg:
$(document).ready(function(){
$("button").click(function(){
$("p").slideToggle();
});
});
Definition and Usage
The ready event occurs when the DOM (document object model) has been loaded.
Because this event occurs after the document is ready, it is a good place to have all other jQuery events and functions. Like in the example above.
The ready() method specifies what happens when a ready event occurs.
note: The ready() method should not be used together with <body onload="">.
From jQuery documentation:
Description: Specify a function to execute when the DOM is fully loaded.
It means that you can specify a function to run after the DOM is fully loaded, ie is available to interact with javascript.
Following is copied from here
$(document).ready(...)
Fire when all DOM loaded (even if multimedia no loaded yet)
$(window).load(...)
Fire when all content loaded (progress indicator which shows loading proccess) gone.
Now here is my suggestion (not from that link)
I think the better approach would be putting your script tags at the end of body, like this, as it makes sure that the script is loaded when everything else has been loaded
<html>
<head></head>
<body>
<div>
bla bla bla
</div>
<script src="1"></script>
.
.
<script src="n"></script>
<script>console.log('hello');</script>
</body>
</html>

Why I need to use `setTimeout()` to make `jquery.animate` work in a backbone view?

I want to invoke jquery.animate directly to change the effect of a div, but found it doesn't have any effect.
Instead, I need to put it inside a setTimeout(..., 0) to make it work.
I wonder why do I need to do this, and is it the best approach?
Live demo
http://jsbin.com/docahu/2/edit
Or here:
var FooView = Backbone.View.extend({
id: 'foo',
});
var BarView = Backbone.View.extend({
render: function() {
$("#foo").animate({width: '200px'});
// !!! HERE !!!
setTimeout(function() {
$("#foo").animate({height: '100px'});
}, 0);
return this;
}
});
var fooView = new FooView();
var barView = new BarView();
var combinedView = $(fooView.render().el).append(barView.render().el);
$(document.body).append(combinedView);
#foo {
width: 50px;
height: 50px;
background-color: blue;
color: white;
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Jquery animate delay problem in backbone render" />
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="//jashkenas.github.io/underscore/underscore-min.js"></script>
<script src="//jashkenas.github.io/backbone/backbone-min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
</body>
</html>
You can see height is changed but the width is not.
PS:
Also I found $(document).ready() is also working:
$(document).ready(function() {
$("#foo").animate({height: '100px'});
});
Which one is better to use?
It's because it's trying to animate the width before the element is in the DOM. If you put a selector in that position, you'll probably find it's not getting anything.
Doing a timeout of 0 (so javascript finishes rendering the things THEN tries the animation) or waiting for the document to finish rendering fixes that
Things happen in this order:
You render your view, but it's unattached to the DOM
the width animation runs. Nothing happens because '#foo' isn't on the DOM.
you attach it to the dom.
your height animation runs. It works because '#foo' is in the DOM.
Well seems like it works by chance. The reason the first one is not working is probably because the object are still not loaded on the screen. The second one is working because after the timer was dispatched and ended (this does not really take 0 time) the page was loaded by another thread on the computer. So the overhead of creating the timer and calling back the procedure is apparently enough to finish loading the page.
You should use $(document).ready to make sure it is always called after the document is fully loaded, because like I said, it is now working by chance, and a different browser\machine may not run any of the two (or both).
Background: JavaScript starts getting executed while the page is loaded, and the DOM is build at the same time (just at the time the HTML and JavaScript text is downloaded). So if you reference DOM objects from JavaScript code like you are doing now, you get a race condition where the outcome is not defined. To avoid that there is the $(document).ready callback.
Edit
See this question. Also the Udacity course is really cool to understand what is going on.
Updated
TL;DR
Using $(document).ready is equivalent to placing the JavaScript at the end of the document…
JSBin (which is were the OP posted his sample code) will execute the JavaScript after all the HTML elements render, but before the $(document).ready event. Binding the jQuery.animate in $(document).ready is the same as firing it anytime after the view is appended to the DOM.
The simple and stable solution is to simply invoke
$("#foo").animate({width: '200px'});
on the last line of the OP's code. (Read the end of the Answer to see a more formal way of binding the jQuery.animate function)
To answer the OP's original quesiton: setTimeout() works in your case because of the way async functions are queue in the JavaScript runtime. If the <body> has already been loaded, then using setTimeout(0) the way the OP does, will have the same effect as placing the animation binding in $(document).ready.
Why setTimeout(0) works
The first thing to understand is that JavaScript is not a multi-threaded framework. While you certainly can invoke non-synchronous functions, asynchronous, async functions don't actually run parallel to the synchronous operations. Instead, async functions are queued to run as soon as the runtime is free.
For example, take the following three synchronous functions.
function1();
function2();
function3();
As you'd expect function1will fire first, followed, in order, byfunction1, function2thenfunction3. However, if I place function1` in an asynchronous call
setTimeout(function1,0);
function2();
function3();
then function1 will be placed on a queue, leaving function2 and then function3 to fire. As soon as the event loop is finished function1 is invoked. That is, it fires last! You can see this in action in this fiddle.
In the OP's example, setTimeout(function() { $("#foo").animate({height: '100px'});}, 0); was fired immediately after the runtime executed $(document.body).append(combinedView); and so jQuery was able to find the #foo element, so technically this is a correct way to do what the OP wants. This is true because of the way JSBin works. That is, it loads the JavaScript from its JavaScript Module after the DOM has loaded (but before the $(document).ready event).
Edited:
Do not use the $(document).ready function...in general
I think there's some confusion regarding how $(document).ready function solves the OP's problem. Most of the confusion probably stems from the complexity of how different web page elements (HTML, CSS, JavaScript) affect the rendering of the DOM.
There is a main parsing and rendering thread used by browsers. This is where your HTML is processed, your CSS stylesheets are fetched and parsed, and your JavaScript is fetched/parsed. All of these operations are executed as they are encountered and will be blocking (unless async or defer is specified in your <link>/<script> tags).
The order in which you pace all of these tags is essential. If your script tag is written at the top of your document (say within the <head> tag) it will be executed before any HTML is injected into the DOM.
In essence, using $(document).ready is equivalent to placing the JavaScript at the end of the document… Since JSBin (which is were the OP posted his sample code) will execute the JavaScript after all the HTML elements render, but before the $(document).ready function, binding the jQuery.animate in $(document).ready is the same as firing it anytime after the view is appended to the DOM.
Instead, the simple and stable solution is to simply invoke
$("#foo").animate({width: '200px'});
after both the fooView and the barView have been attached to the DOM. Or more formally:
var BarView = Backbone.View.extend({
render: function() {
// process your html here
return this;
}
bindTransitions: function {
$("#foo").animate({width: '200px', height: '100px'});
}
});
var fooView = new FooView();
var barView = new BarView();
var combinedView = $(fooView.render().el).append(barView.render().el);
$(document.body).append(combinedView);
barView.bindTransitions();
If you've properly scoped your backbone view, you should be able to reference the element that is currently in memory when you are trying to change the width or height (pre-render).
You can do this by doing something similar to: this.$el.find(#foo") to obtain access / manipulate to your markup before it is added to the DOM.

Reload? Javascript after Jquery .live/.load

I wanted to load some fragments of external content inside a div, through a menu.
Found "load" and "live", found a tutorial used it = success!
Except, like what's explicit in the documentation, it doesn't load JavaScript.
The thing is, the destination page already loads, inside the header, that same JavaScript, 'cause Wordpress loads it in every page. In this particular page, I'm only using the plugin (nextgen gallery) through the jQuery AJAX call.
So, what I believe is my problem is that I somehow need to alert/reload the JavaScript, right?
And how can I do this?
<script type="text/javascript" charset="utf-8">
jQuery(document).ready(function(){
// ajax pagination
jQuery('#naveg a').live('click', function(){ // if not using wp-page-numbers, change this to correct ID
var link = jQuery(this).attr('href');
// #main is the ID of the outer div wrapping your posts
jQuery('#fora').html('<div class="loading"><h2>Loading...</h2></div>');
// #entries is the ID of the inner div wrapping your posts
jQuery('#fora').load(link+' #dentro')
return false;
});
}); // end ready function
</script>
PS: I've substituted "live" with "on" but didn't work either.
I'm not sure if I understand... your load() command is puling in some Javascript that you want executed? I'm not sure if you can do that. But if you just need to call some JS upon load() completion, you can pass it a function like so:
jQuery('#fora').load(link+' #dentro', function() {
console.log("load completed");
// JS code to be executed...
});
If you want to execute Javascript code included in the loaded page (the page you retrieve via .load()), than you have to use the url-parameter without the "suffixed selector expression". See jQuery documentation for (.load()):
Note: When calling .load() using a URL without a suffixed selector expression, the content is passed to .html() prior to scripts being
removed. This executes the script blocks before they are discarded. If
.load() is however called with a selector expression appended to the
URL, the scripts are stripped out prior to the DOM being updated,
which is why they are never executed. An example of both cases can be
seen below:
Here, any JavaScript loaded into #a as a part of the document will
successfully execute.
$('#a').load('article.html');
However in this case, script blocks in the document being loaded into
#b are stripped out prior to being executed:
$('#b').load('article.html #target');
I think that's your problem (although I have no solution for you, sorry).
Proposal: Maybe you can load the whole page (including the Scripts) and remove (or hide) the parts you don't need?
Cheers.

jQuery not getting called in all browsers

Disclaimer: I am new to jQuery.
I am trying to implement a fadeOut effect in jQuery for a div block, and then fadeIn effect on two other div blocks.
However, these effects are only working in the Chrome browser (i.e. they won't work in Safari, FireFox, Opera) which is rather perplexing to me. I have tried clearing my cache in case it was storing an old file, but none of that seemed to do anything.
Basic idea (stored in mainsite.js file):
$("#videoThumbnail_XYZ").click(function () {
$("#thumbnailDescription_XYZ").fadeOut(300);
$("#videoPlayer_XYZ").delay(300).fadeIn(100);
$("#videoHiddenOptions_XYZ").delay(300).fadeIn(100);
});
So when a div tag with the id of videoThumbnail_XYZ is clicked, it starts the fadeOut and fadeIn calls on the other div tags.
I am loading my javascript files into the page in this order (so jQuery is loaded first):
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
<script async="" type="text/javascript" src="javascripts/mainsite.js"></script>
Any guidance you could give is greatly appreciated!
Make sure the DOM is fully loaded before your code runs.
A common way of doing this when using jQuery is to wrap your code like this.
$(function() {
$("#videoThumbnail_XYZ").click(function () {
$("#thumbnailDescription_XYZ").fadeOut(300);
$("#videoPlayer_XYZ").delay(300).fadeIn(100);
$("#videoHiddenOptions_XYZ").delay(300).fadeIn(100);
});
});
This is a shortcut for wrapping your code in a .ready() handler, which ensure that the DOM is loaded before your code runs.
If you don't use some means of ensuring that the DOM is loaded, then the #videoThumbnail_XYZ element may not exist when you try to select it.
Another approach would be to place your javascript code after your content, but inside the closing </body> tag.
<!DOCTYPE html>
<html>
<head><title>your title</title></head>
<body>
<!-- your other content -->
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
<script async="" type="text/javascript" src="javascripts/mainsite.js"></script>
</body>
</html>
If mainsite.js is being included before your div is rendered, that might be throwing the browsers for a loop. Try wrapping this around your click handler setup:
$(document).ready(function(){
// your function here
});
That'll make sure that isn't run before the DOM is ready.
Also, you might consider putting the fadeIn calls in the callback function of your fadeOut, so if you decide to change the duration later on, you only have to change it in one place.
The way that'd look is like this:
$("#thumbnailDescription_XYZ").fadeOut(300,function(){
$("#videoPlayer_XYZ").fadeIn(100);
$("#videoHiddenOptions_XYZ").fadeIn(100);
});
I see you have a delay set to the same duration your fadeOut is, I would recommend instead of delaying which in essence your waiting for the animation to complete that instead you use the callback function.
$("#videoThumbnail_XYZ").click(function () {
$("#thumbnailDescription_XYZ").fadeOut(300, function() {
$("#videoPlayer_XYZ").fadeIn(100);
$("#videoHiddenOptions_XYZ").fadeIn(100);
});
});
While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code.
$(document).ready(function(){
$("#videoThumbnail_XYZ").click(function () {
$("#thumbnailDescription_XYZ").fadeOut(300);
$("#videoPlayer_XYZ").delay(300).fadeIn(100);
$("#videoHiddenOptions_XYZ").delay(300).fadeIn(100);
});
});
All three of the following syntaxes are equivalent:
* $(document).ready(handler)
* $().ready(handler) (this is not recommended)
* $(handler)

Categories

Resources