In JS / jQuery there's often a need to do something and then repeat it under certain circumstances.
For example something like this, it's only an example:
$(window).load(function() {
scaleSomething();
$(window).resize(function() {
scaleSomething();
});
});
What would be the elegant way to write something like this? Because in such situations one function / block of code is always doubled.
You have to use .on to bind multiple events. Please read here to know more about it.
Try,
$(window).on('load resize',scaleSomething)
You can group space-separated events when using ".on" method:
$(window).on("load resize", function() {
scaleSomething();
});
http://api.jquery.com/on/
Try to trigger the event immediately after you create a listener:
$(window).on('resize', function() {
scaleSomething()
}).trigger('resize');
Use on to attach an event handler to multiple events. The events are passed as the first argument to the on function. The argument should be a string with event names delimited by spaces.
$(window).on("load resize", function(){
scaleSomething();
});
function scaleSomething(){
alert("scaling");
}
JS Fiddle: http://jsfiddle.net/7ZFpr/
Related
I would like to call function when slideUp or slideDown are performed on an element. Is this possible?
Something like:
$('#panel').on('slideUp', function() { open--; });
$('#panel').on('slideDown', function() { open++; });
Update: The problem is that there are a ton of slide calls (e.g.: $().slideUp()) all over the page, within ajax responses, hash link clicks, etc.. I was hoping to bind to the slide itself somehow rather than add code to each calling function.
You cannot bind to an event since there is no such.
But you can pass a handler that will be called after animation is finished
$('#panel').slideUp(function() { ... });
http://api.jquery.com/slideUp/
If you really want to do this, you can use custom events and your own little plugin, something like this:
$.fn.mySlideToggle = function() {
this.slideToggle();
this.trigger('mySlideToggle');
}
$('div').on('mySlideToggle', function(){ console.log('hey') });
$('button').on('click', function(){ $('div').mySlideToggle(); });
Here's a little demo (check console): http://jsbin.com/asejif/2/edit
In your case it is redundant though, since you can use the callback that the slide events provide, but it might be useful for other things...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
jQuery 1.7 - Turning live() into on()
I have with jQuery:
$(".house td[red]").live("click", function() {
alert('ok');
});
but function live is deprecated. How can i use on?
$(".house td[red]").on("click", function() {
alert('ok');
});
not working.
$(".house").on("click", 'td[red]', function() {
alert('ok');
});
have you tried this? You can check in documentation for details. Example from there:
$("#dataTable tbody").on("click", "tr", function(event){
alert($(this).text());
});
So you basically pass a "container" for wrapper. The reason why live is not recommended is that it can be written with "on" syntax like this:
$(document).on("click", '.house td[red]', function() {
alert('ok');
});
which you can see is not very efficient. Probably there's more to that :) so it is good you want to change it.
Use it as -
$(document).on("click", ".house td[red]", function() {
alert('ok');
});
The more efficient way is using .on() with immediate parent of the element -
$('.house').on("click", "td[red]", function() {
alert('ok');
});
Read here for better understanding of difference between live and on
on() is an all-things-to-all-men function that can work in different ways - both with direct and delegated events. live() was a means of achieving delegated events. This is achieved with on() by passing a filter as param 2, and bumping the callback to param 3:
$(".house").on("click", 'td[red]', function() {
alert('ok');
});
It's a three-argument variant, and you get to pick the "bubble" point:
$('body').on('click', '.house td[red]', function() { alert("ok"); });
The difference is that with this, the point at which the actual event handler is placed is under your control (like with the also-deprecated .delegate()). You can pick any parent element you like, which is a nice feature in complicated pages. (In your case, for example, you could put the handler on all the ".house" elements instead of the body.)
$(document).on('click', '.house td[red]', function(){
alert('ok');
});
Document is the static element we wish to attach our handler to.
First param is the event
Second param is the selector
Third param is the functions you wish to run against the selector when the event is fired.
Try this,
$(document).on("click", ".house td[red]", function() {
alert('ok');
});
$(".house td[red]").live("click", function() {
alert('ok');
});
Would be directly converted to this:
$(document).on("click", ".house td[red]", function() {
alert('ok');
});
But you can gain some performance by specifying the closest container that you know will exist at the time of the bind:
$('#someContainer').on("click", ".house td[red]", function() {
alert('ok');
});
$(document).on("click",".house td[red]",function(){
alert('ok');
});
Say I have some code like this which is called on $(document).ready()
$(".someClass").click(function(){
//do something
});
Later on I have some jquery to create an element with the class someClass. Is there anyway to automatically attach the click from above or do I have to manually attach it again?
Yes. It is possible.
$("body").on("click", ".someClass", function() {
// ...
});
Use latest version of jquery and on
$(document).on('click', '.someClass', function(e){
//do something
});
Live is deprecated but you can use it, anyway (not recommended).
$('.someClass').live('click', function(e){
//do something
});
There is live, which also listens for new elements
$(".someClass").live('click', function(){
//do something
});
But, as of jquery 1.7 it has been deprecated. It's advised to use on instead.
But in order to use on, you need a container for the elements you want to bind a handler. Of course you could use body or document but it's better to use a more specific element
$(".someClassContainer").on('click', '.someClass' function(){
//do something
});
There's two easy ways of doing this, the first is with on():
$(".someClassParentElementPresentInTheDOMonDOMReady").on('click','.someClass',
function(){
//do something
});
And the other is to simply assign the click-handler at the point of creation of the new element; I don't know how you're doing that, but an example is below:
$('#addElement').click(
function(){
var newElem = $('<div />',{'class' : 'someClass'}).click(function(){
// do something }).appendTo('.someClassParentElementPresentInTheDOMonDOMReady');
References:
on().
lets say I have
function trigger(){
$('a.pep').each(function(){
$('a.pep').click(function(){
console.log($(this).val());
});
});
}
function push(){
$('body').append('<a class="pep">hey mate i have no trigger yet</a>');
trigger(); //now i do but the others have duplicated trigger
}
$(document).ready(function(){
$('a.push').click(function(){
push();
});
});
So it seems that the click event is being applied twice/+ because the console.log is lauched more than once by click
How can i prevent this?
The problem is that you call $('a.pep').click() lots of times. (In fact, you bind as many click handlers as there are matching elements to each element. And then you do it again every time one of them is clicked.)
You should lever the DOM event bubbling model to handle this. jQuery helps you with the on method:
$(document.body).on('click', 'a.pep', function() {
console.log('element clicked');
$(document.body).append('<a class="pep">Click handlers handled automatically</a>');
});
See a working jsFiddle.
Note that I have removed the val call, because a elements can't have a value... Note also that the on method is introduced in jQuery 1.7; before that, use delegate:
$(document.body).delegate('a.pep', 'click', function() {
Small change to your trigger function is all you need. Just unbind the click event before binding to ensure that it is never added more than once. Also, you don't need to use each when binding events, it will add the event to each item automatically.
function trigger(){
$('a.pep').unbind('click').click(function() {
console.log($(this).val());
});
}
You can check using data('events') on any element if the required event is attached or not. For example to check if click event is attached or not try this.
if(!$('a.pep').data('events').click){
$('a.pep').click(function(){
console.log($(this).val());
});
}
you should use jQuery live here because you add DOM elements dynamicly and you want them to have the same click behaviour
function push(){
$('body').append('<a class="pep">hey mate i have no trigger yet</a>');
}
$(document).ready(function(){
$('a.push').click(function(){
push();
});
$('a.pep').live('click', function(){
console.log($(this).val());
});
});
Try:
if($('a.pep').data('events').click) {
//do something
}
i think if you use live() event you dont need to make function
$('a.pep').live('click', function(){
console.log($(this).val());
});
In many cases, I need to bind a behaviour to an element after loading, and then after an event triggering (like "change").
I think the best way would be to make it in the same line:
$('#element_id').bind('load, change', function () {
...
});
But this works only for "change" and not for "load". There is a better way?
I stumbled across the same problem. Removing comma is not enough, at least not in this case:
$(document).ready(function(){
$('#element_id').bind('load change', function () {
... // (this DOESN'T get called on page load)
});
});
I guess load events get triggered before $(document).ready().
This is a simple solution:
$(document).ready(function(){
$('#element_id').bind('change', function () {
...
});
$('#element_id').trigger('change');
});
For already loaded content, when you want to run a function on an event and also straight away, you can use a custom event of your own naming to avoid triggering any existing bindings from libraries etc. on the built in events, e.g.
$(".my-selector").on("change rightnow", function() {
// do stuff...
}).triggerHandler("rightnow");
Don't you just need to remove the comma?
try it without the comma:
$('#element_id').bind('load change', function () {
...
});
http://api.jquery.com/bind/#multiple-events