Can jQuery ready() function be used twice for the same element? - javascript

I want to use jQuery ready() function for the document element. Here are my scripts:
1st page:
$(document).ready(function(){
$('form#haberekle').ajaxForm(options);
});
2nd page:
$(document).ready(function() {
var options = {
success:showResponse,
beforeSubmit:showRequest,
resetForm:true
};
$('#haberresmiekleform').ajaxForm(options);
});
These two pages are included in the same main page with <!--#include file=""-->
Can these two functions work properly, or they block each other?
According to my experience they seem work properly.
For example: an onclick function of a button is only one.

You can have as many .ready() calls as you want, jQuery is designed with this in mind and it's absolutely ok.
So yes, it is ok, and you won't have any problems...this happens all the time.
Think of it as an event handler, like .click(), this is exactly how it behaves (well, strictly speaking, not exactly, but for most purposes like this). So you can have as many as you want.
One more note that may be of interest, the handlers you pass into .ready() are pushed via .done() to the readyList, which means they'll execute in the order you called them in the page. The same order behavior is true (though via an array, a different method) in earlier versions of jQuery.

Yes, that is fine. Both will be called when the dom is fully loaded. Note that if you call .ready() after the dom is already loaded, the callback will be executed immediately. See http://api.jquery.com/ready/

Yes, you can.
Take a look here:
http://www.learningjquery.com/2006/09/multiple-document-ready

No problem attaching several handlers for the same event. The documentation for ready says :
There is also
$(document).bind("ready", handler).
This behaves similarly to the ready
method but with one exception: If the
ready event has already fired and you
try to .bind("ready") the bound
handler will not be executed.
And the documentation for bind says:
When an event reaches an element, all
handlers bound to that event type for
the element are fired. If there are
multiple handlers registered, they
will always execute in the order in
which they were bound

Related

Extra function tag needed?

In this example someone shows a jQuery onclick event.
My shows this:
$(function() {
$('.post').on('click', function() {
SOME STUFF
});
});
But what are the first and last line doing?
if i remove the lines, it's not working:
$('.post').on('click', function() {
SOME STUFF
});
But why? In the linked example is a second commenter. He shows this way (without first/last line).
Can someone explain this?
It is a shortcut for $( document ).ready(...)
See http://api.jquery.com/ready/
Quoting the doc :
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. [...]
All three of the following syntaxes are equivalent:
* $( document ).ready( handler )
* $().ready( handler ) (this is not recommended)
* $( handler )
That is short for document.ready. It waits until the entire document is loaded and the element with class .post can be found and bound to.
If you omit that part, the jQuery function will not find the element and your event will not work.
The first and last lines create an anonymous function. In computer programming, an anonymous function is a function defined, and possibly called, without being bound to an identifier.
In the example here it is used to set the event listener that is loaded onload of the page.
$(function() {
$('.something').on('click', function() {
alert('hello');
$(this).addClass('classOne');
});
});
$(function(){});
is jQuery short hand for
$(document).ready(function() {});
which ensures your document is ready for manipulation before executing anything within it. In many ways its similar to the browser window.onready event. See jQuery docs..
The risk if you don't wrap your jQuery code in either of these forms of the functions is that you will try and manipulate elements before they have been created by the browser. Your code is not guaranteed to fail, but you could, at the very least, get inconsistent behaviour.

Using jQuery .on() for all events

Is it considered bad practice to use jQuery's .on() event handler for every event?
Previously, my code contained script like this:
$('#cartButton').click(function(){
openCart();
});
However I've recently started using InstantClick (a pjax jQuery plugin).
Now none of my scripts work. I understand why this is happening, but I cannot wrap my code with the InstantClick.on('change', function(){ tag as this means my code starts to repeat itself. For example, clicking on the cart button will run the openCart() function many times. So to get around this, I'm changing all my functions to something like this:
$(document).on('click', '#cartButton', function(){
openCart();
});
I'm curious as to whether this will increase loading times and cause excess strain. Is it bad practice to use the on() event handler for every event in my code?
It's not bad practice at all..
.on is the preferred method for handling all events, and using .click is just a shortcut that gets passed to the .on method anyway..
If you check out here (unminified source for jquery 2.1.0): https://code.jquery.com/jquery-2.1.0.js
Here are a couple notes:
search for this line: on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
This is the function definition for the on method and just shows you what the code is doing..
also search for this line: jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick "
Th code below this line is mapping all the directly callable shortcuts (like click) and shows you that they are just mapping to the 'on' method.
Hope this helps!!!
No it is not a bad practice to use .on(), actually if you check the source of the .click() function, you'll see that it actually calls .on().
But... Instead of creating an anonymous function, you should simply do this, which would be cleaner, and slightly faster:
$(document).on('click', '#cartButton', openCart);
and
$('#cartButton').click(openCart);

Why when initiating $.click() several times, and if the link is clicked once, it captures it more than once?

I have something like:
function init(){
$('.btn').click(function(){
//do something;
}
}
And when new content is added via ajax, I'm calling init(), so that click event applies to new buttons. But when I click it once, it captures several clicks (as many times as I called init()). It makes sense, but how to avoid it?
jsFiddle link: http://jsfiddle.net/s2ZAz/8/
Solutions:
* Use $.delegate() - http://api.jquery.com/delegate/
* Use $.live() - http://api.jquery.com/live/
Less preferred, but still, solutions:
* Use $.off() - http://api.jquery.com/off/ or $.unbind() - http://api.jquery.com/unbind/
click says, "for every object matching the selector, hook up this click listener". You probably want something more like delegate that says "for every object that will ever match this selector, hook up this listener".
$(document).delegate('button', 'click', function() {
});
You will still get double callbacks if you call init twice, but in this manner, you won't have to call init twice, because as new objects are added, they'll already be assigned to click listeners.
Note that document above should be replaced with the nearest persistent ancestor, as per Greg's comment below.
Demo.
Since jQuery 1.7, you can preferably use the .on() function to achieve the same effect.
Demo.
You can use the unbind method to remove the event handler (or the off method if you're using the new jQuery 1.7 syntax for attaching handlers)
Better yet, you can use the live method, to set up the event handler for any elements that are added to the page in the future and match the given selector. In this way you only have to call init once.
$("body").delegate("button", "click", function() {
alert('I\'m annoying!');
});
$('div').append("<button>Click me, I will alert twice</button><br/>");
$('div').append("<button>Click me, I will alert once</button><br/>");
$('div').append("<button>Click me, I will not alert at all</button><br/>");
Try it out
As mentioned by David, and as per liho's delegate example (loved the way the fiddle cascaded how many times the alert would pop!!), the problem is with multiple bindings, which can be solved with .live() (deprecated) or .delegate() (being phased out), or .on() (the preferred). However, it is a mistake to delegate listening to the document or even body node in terms of performance.
A better way to do this is identify an ancestor of the button that will not ever be destroyed. body is an easy choice, but it's almost always the case that we build our pages with wrapper elements of some sort, which are nested one or more levels deeper than body and therefore allow you to set fewer listeners.
HTML:
<div id="someWrapper">
<div class="somethingThatGetsDestroyed">
<button>Click Me</button>
</div>
</div>
JS using jQuery 1.7+:
$('#someWrapper').on('click', 'button', function() {
alert('Clickity-click!');
});

Jquery function firing

A quick question really.. Could someone explain why the first example would work, yet the second does not.
$(function()
{
$("#select_one").change(function()
{
alert('efjwelf');
});
});
### Example 2
$("#select_one").change(function()
{
alert('efjwelf');
});
Thanks in advance
Because the #select_one object doesn't exist until the DOM is fully loaded. $function(){...}) is shorthand for $(document).ready(function() {...})
In the second example, the element you are binding (#select_one) to does not exist yet, so the event listener doesn't get binded to anything.
When you call bind (or change, or other shortcut methods), the event listener only gets attached to the elements that the selector matches at that time. Elements added in the future do not get attached. To get around this, these methods are used:
$(document).ready(function(){/*...*/}) or $(function(){/*...*/}) - This makes sure the document is ready before attaching events.
$("selector").live(function(){/*...*/}) - This attaches the listener to all elements that match the selector, now or in the future.
$("root").delegate("selector", "click", function(){/*...*/}) - This attaches the listener to all elements that match the selector with a root elements, now or in the future.
On the second one, element that you are trying to attach an event handler is not available yet.
Check this: http://api.jquery.com/ready/
All three of the following syntaxes are equivalent:
$(document).ready(handler)
$().ready(handler) (this is not recommended)
$(handler)
It's a matter of when the DOM is ready/loaded.
if element with id='select_one' exists at the time of execution of both scripts - they will both work.

difference between jQuery.live and jQuery.delegate

I have read some post about why do not use jQuery.live() and I want to check if I got it:)
When I call $("body").delegate('element','click', function);
Is it the same as $(element).live('click', function) ?
In case of normal behaviour..According to the post there are some stopPropagation and performance boons, but is the main difference that live bind everytime to body element, while delegate can bind to another one?
One important difference is that ".live()" will actually build up the jQuery element list for the initial selector, even though the ".live()" function itself only needs the selector string. That means that if the selector is somewhat expensive, the code to set up the handler will go running all over the DOM for no good reason. The ".delegate()" call does not do that.
Really I don't see any reason that new code should use ".live()"; it was sort-of an architectural mistake and should eventually die quietly.
Nettuts has a screencast just to explain this: Quick Tip: The Difference Between Live() and Delegate()
Quote from the site:
// Live(), introduced in 1.3, allows for the binding
// of event handlers to all elements that match a
// selector, including those created in the future.
// It does this by attaching the handler to the document.
// Unfortunately, it does not work well with chaining.
// Don't expect to chain live() after calls like
// children().next()...etc.
$("li").live("click", function() {
$(this).parent().append("<li>New Element</li>");
});
// Delegate, new to version 1.4, perhaps should have been a complete
// replacement for Live(). However, that obviously
// would have broken a lot of code! Nonetheless,
// delegate remedies many of the short-comings
// found in live(). It attaches the event handler
// directly to the context, rather than the document.
// It also doesn't suffer from the chaining issues
// that live does. There are many performance benefits
// to using this method over live().
$('#items').delegate('li', 'click', function() {
$(this).parent().append('<li>New Element</li>');
});
is the main difference that live bind everytime to body element, while delegate can bind to another one?
Yes, exactly. Let's say you have a table that you add and remove rows from, and you want to handle clicks on those rows (or links or buttons within the rows). You could use live for that, but then the event has to bubble all the way down to the body level and let's face it, it feels a bit like a global variable. If you use delegate on the table element instead, you remain more targeted, isolated from other things going on on the page. delegate is a more modular, contained version of live.
Since the .live() method handles events once they have propagated to the top of the document, it is not possible to stop propagation of live events. Similarly, events handled by .delegate() will always propagate to the element to which they are delegated; event handlers on any elements below it will already have been executed by the time the delegated event handler is called.
The short of it is that .live runs at the document level and .delegate runs on whatever element you specify. Why does it make a difference? If you have a mousemove event (or several) bound using .live, jQuery will execute code every time you move your mouse anywhere on the page to see if your callback function should run. This is extremely inefficient and is the reason for having .delegate. .delegate functions only run when the even originates inside of the dom node you specify. If, for example, you said $('ul#myUL').delegate(...), then jQuery would only check to see if the code should run when the event originated from within ul#myUL

Categories