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().
Related
I was wondering if Javascript or jQuery have a way to delete an event listener. Let's say I want to make a function that I want to trigger only once, for example let's say I want to have a button that shows some hidden elements on the document, I would make this function (assuming the hidden elements have a hidden class that hides them):
jQuery('#toggler').click(function() {
console.log('Hidden elements are now shown');
jQuery('.hidden').removeClass('hidden');
});
Simple enough, right ? Now, my actual problem comes in, I don't want jquery to run that function again and again each time the button is clicked, because the elements are already revealed, so is there a clean way to do it ? So, in this example after clicking the toggler multiple times I want to get only one console message.
I could do jQuery(this).unbind('click'), but this results into removing ALL triggers and I only want to remove the current trigger.
What I usually do when I face such scenarios is solve it like this (which is ugly and doesn't actually prevent code execution, but only handles the code's results) :
var toggler_clicked = false;
jQuery('#toggler').click(function() {
if(toggler_clicked) return;
toggler_clicked = true;
console.log('Hidden elements are now shown');
jQuery('.hidden').removeClass('hidden');
});
Also I don't want to use jQuery's one, because I will have the same problem when I'll need to delete the trigger conditionally, so if you can help please give me a dynamic answer.
Thanks in advance !
You have to name your function like that:
var myFunction = function() {
console.log('Hidden elements are now shown');
jQuery('.hidden').removeClass('hidden');
};
And bind it this way
jQuery('#toggler').click(myFunction);
Then you can unbind it with :
jQuery('#toggler').off('click',myFunction);
Without unbinding the other listeners
You can try this:
var myFunc = function() {
console.log('Hidden elements are now shown');
jQuery('.hidden').removeClass('hidden');
jQuery(this).unbind('click', myFunc);
};
jQuery('#toggler').click(myFunc);
This way of calling unbind is such that only the listener for myFunc handler is removed and not all the events connected to the click on the toggler.
I would use the .on() and its opposite .off() methods to attach/detach the event handler. It is the recommended way since 1.7 instead of the .bind() and .unbind() versions that became deprecated as of jQuery 3.0.
$("#toggler").on("click", function(event) {
console.log('Hidden elements are now shown');
$('.hidden').removeClass('hidden');
// if (/* Add your condition here */) {
$(this).off(event);
// }
});
$("#toggler").on("click", function(event) {
console.log('Hidden elements are now shown');
$('.hidden').removeClass('hidden');
// if (/* Add your condition here */) {
$(this).off(event);
// }
});
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="toggler">Toggle</button>
<div class="hidden">
HIDDEN
</div>
Try this
var myFunction = function() {
console.log('Hidden elements are now shown');
jQuery('.hidden').removeClass('hidden');
};
Add the event listener like this:
jQuery('#toggler').addEventListener("click", myFunction);
And remove it like this:
jQuery('#toggler').removeEventListener("click", myFunction);
So all together this will do the trick:
var myFunction = function() {
console.log('Hidden elements are now shown');
jQuery('.hidden').removeClass('hidden');
jQuery('#toggler').removeEventListener("click", myFunction);
};
jQuery('#toggler').addEventListener("click", myFunction);
more about the HTML DOM removeEventListener() Method
Jquery unbind function takes 2 parameters eventType and handler
You can put your event listener into separate function like this:
var clickEventHandler = function(){
//your logic goes here
}
After you add listener as reference:
jQuery('#toggler').click(clickEventHandler);
And then, later, anytime, anywhere you want you can unbind that specific handler:
jQuery('#toggler').unbind('click', clickEventHandler);
What i used to do in the past is toggle the click behavior using css classes, ex i used to set a click listener on the parent and delegate to all of the children something that jquery is doing now by default i believe. Anyway based on the css class it will trigger an event for ex.
$('.some-parent-element').on(
'click',
'the-behavior-css-class',
function() { // do stuff here.... }
)
Now if you want to remove this behavior you can just toggle the class of the element and it should do the job. ex
$('.some-parent-element').on(
'click',
'hide-me-on-click-or-whatever',
function() {
$(this).toggleClass('hide-me-on-click-or-whatever')
// perform the action
}
)
You can check if the element has the class hidden
Often there is situation when I need to add some event with some customizations and then apply those customizations on page ready.
Usually I was doing it like:
$(window).resize(function(){
//some code
}).resize(); //trigger it when event defined
Problem with this solution is that if I have many resize events, then if I trigger it like this - it will re-execute all previously defined events too.
So another solution could be:
var myCallback = function(){ /*some code*/ };
$(window).resize(function(){
myCallback();
});
myCallback();
And it does it correctly but I find it not so good looking code and also there is no this inside function changed to event target DOM element that is very useful quite often.
Great would be something like
$(window).addEventAndFireOnce("resize", function(){});
such function is not so hard to implement, but I'm wondering if there is something like this there already in js or jQuery.
I don't know if I'm alone in this, but if I need to do that (and it's not uncommon) I bind a custom event name (possibly with a scope) at the same time as I bind the real event ("click" or "change" or whatever):
var myCallback = function(ev) { ... };
$(window).on("resize my-resize", myCallback).trigger("my-resize");
That's particularly useful when you're handling something like a "click" event on a checkbox. Triggering the "click" will actually update the checkbox "checked" state, which is not generally what you'd want to do. There's the jQuery .triggerHandler() method, but for whatever reason that only works on the first element in the jQuery object, so you can't trigger the handlers for all the checkboxes in a form with one call.
I would write it like so:
var myCallback = function(){ /*some code*/ };
$(window).resize( myCallback );
myCallback();
I think what you are looking for here is namespaced handlers
var log = (function() {
var $log = $('#log');
return function(msg) {
$('<p/>', {
text: msg
}).appendTo($log)
}
})();
$(window).resize(function() {
log('handler 1');
});
$(window).resize(function() {
log('handler 2');
});
$(window).on('resize.myspecial', function() {
log('handler 3');
}).trigger('resize.myspecial');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="log"></div>
In jQuery you can dynamically bind an event listener to all future instances of divs with a class of 'subthing' by binding to a parent element and assigning a filter like so:
$(".thing").on("click", ".subthing", function(){
console.log('subthing clicked');}
);
If I have a jquery plugin that I would ordinarily bind with
$(".subthing").thingify();
Is there an established way ensure that all future instances of .subthing will also have the plugin attached to them?
Try:
document.body.addEventListener("DOMNodeInserted", function(event){
var $elementJustAdded = $(event.target);
if ($elementJustAdded.hasClass('subthing')) {
$elementJustAdded.thingify();
}
}, false);
Take a look at the livequery plugin
$(".subthing").livequery(function(){
$(this).thingify();
});
I think this is exactly what you need.
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());
});
Assuming I have a HTML link in my rows inside a datagrid or repeater as such
DoSomething
Now also assuming that I have handled the click event for all my DoSomethings in jQuery as such
$(".DoSomething").click(function (e) {
//Make my DoSomethings do something
});
What is the correct technique for passing data to the click event that is dependent on the link clicked?
Without jQuery you would typically do something like this.
DoSomething
but this technique obviously doesn't work in the jQuery case.
Basically my ideal solution would somehow add values for to the jQuery.Data property for the link clicked but doing so declaratively.
Use HTML5 data- attributes. jQuery support is built-in for 1.4.3+
http://api.jquery.com/data/#data2
click here
$('.product-link').click(function (e) {
alert($(this).data('productid'));
});
You could use the attr() function.
http://api.jquery.com/attr/
$("#Something").attr("your-value", "Hello World");
$("#Something").click(function (e) {
//Make my DoSomethings do something
var value = $(this).attr("your-value");
alert(value); // Alerts Hello World
});
your question was not clear to me but may be this will help
$(".DoSomething").click(function (e) {
//Make my DoSomethings do something
$(this).data("key","value");
//later the value can be retrieved like
var value=$(this).data("key");
console.log(value);// gives you "value"
});