This question already has answers here:
jquery .off(): how to remove a certain click handler only?
(4 answers)
Closed 3 years ago.
if have a small jsfiddle example:
https://jsfiddle.net/skmqjwt7/
I have multiple eventlisteners. All listening the same event (button.a click in the fiddle example). Now I want to disconnect one event listener, but I DON'T(!) want to disconnect all eventlisteners and reconnect those i want to keep.
I got multiple classes which got some event listeners and i want to disconnect just the eventlisteners of one class.
class a{
...stuff
$('#main').on('bla', function(e){
...stuff
});
}
class b{
...stuff
$('#main').on('bla', function(e){
...stuff
});
function disconnectMe()
{
//disconnect B on('bla')
}
}
class B doesnt know A (or any other classes which might listen to that event). So i just want to remove the eventlisteners of B, while keeping the eventlisteners of all other classes alive.
I cant handle thise disconnects globally like:
$('#main').off();
a.reconnect();
c.reconnect();
In my case class B is just getting data from backend and decides to stop listening to the event on its own.
Is this possible? In my current case, a custom event is triggered on $(document) and any other javascript class is able to listen, but i dont know how to remove just one listener.
The unbind() Method is an inbuilt method in jQuery which is used to remove any selected event handlers. This method can be used to remove particular event handler, or stop specific functions. It works on any event handler using an event object.
Note: If no parameters are provided, the method works on all event handlers from the specified element.
Syntax:
$(selector).unbind(event, function, eventObj)
Parameters: This method accepts three parameters as mentioned above and described below:
event: It is an optional parameter which is used to specify events (one or more) to remove them from the elements.
function: It is an optional parameter which is used to specify the name of the function to unbind from the specified event for the element.
eventObj: It is an optional parameter which is used to specify the event object to remove from the event binding function.
I have an input type="image". This acts like the cell notes in Microsoft Excel. If someone enters a number into the text box that this input-image is paired with, I setup an event handler for the input-image. Then when the user clicks the image, they get a little popup to add some notes to the data.
My problem is that when a user enters a zero into the text box, I need to disable the input-image's event handler. I have tried the following, but to no avail.
$('#myimage').click(function { return false; });
jQuery ≥ 1.7
With jQuery 1.7 onward the event API has been updated, .bind()/.unbind() are still available for backwards compatibility, but the preferred method is using the on()/off() functions. The below would now be,
$('#myimage').click(function() { return false; }); // Adds another click event
$('#myimage').off('click');
$('#myimage').on('click.mynamespace', function() { /* Do stuff */ });
$('#myimage').off('click.mynamespace');
jQuery < 1.7
In your example code you are simply adding another click event to the image, not overriding the previous one:
$('#myimage').click(function() { return false; }); // Adds another click event
Both click events will then get fired.
As people have said you can use unbind to remove all click events:
$('#myimage').unbind('click');
If you want to add a single event and then remove it (without removing any others that might have been added) then you can use event namespacing:
$('#myimage').bind('click.mynamespace', function() { /* Do stuff */ });
and to remove just your event:
$('#myimage').unbind('click.mynamespace');
This wasn't available when this question was answered, but you can also use the live() method to enable/disable events.
$('#myimage:not(.disabled)').live('click', myclickevent);
$('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });
What will happen with this code is that when you click #mydisablebutton, it will add the class disabled to the #myimage element. This will make it so that the selector no longer matches the element and the event will not be fired until the 'disabled' class is removed making the .live() selector valid again.
This has other benefits by adding styling based on that class as well.
This can be done by using the unbind function.
$('#myimage').unbind('click');
You can add multiple event handlers to the same object and event in jquery. This means adding a new one doesn't replace the old ones.
There are several strategies for changing event handlers, such as event namespaces. There are some pages about this in the online docs.
Look at this question (that's how I learned of unbind). There is some useful description of these strategies in the answers.
How to read bound hover callback functions in jquery
If you want to respond to an event just one time, the following syntax should be really helpful:
$('.myLink').bind('click', function() {
//do some things
$(this).unbind('click', arguments.callee); //unbind *just this handler*
});
Using arguments.callee, we can ensure that the one specific anonymous-function handler is removed, and thus, have a single time handler for a given event. Hope this helps others.
maybe the unbind method will work for you
$("#myimage").unbind("click");
I had to set the event to null using the prop and the attr. I couldn't do it with one or the other. I also could not get .unbind to work. I am working on a TD element.
.prop("onclick", null).attr("onclick", null)
If event is attached this way, and the target is to be unattached:
$('#container').on('click','span',function(eo){
alert(1);
$(this).off(); //seams easy, but does not work
$('#container').off('click','span'); //clears click event for every span
$(this).on("click",function(){return false;}); //this works.
});
You may be adding the onclick handler as inline markup:
<input id="addreport" type="button" value="Add New Report" onclick="openAdd()" />
If so, the jquery .off() or .unbind() won't work. You need to add the original event handler in jquery as well:
$("#addreport").on("click", "", function (e) {
openAdd();
});
Then the jquery has a reference to the event handler and can remove it:
$("#addreport").off("click")
VoidKing mentions this a little more obliquely in a comment above.
If you use $(document).on() to add a listener to a dynamically created element then you may have to use the following to remove it:
// add the listener
$(document).on('click','.element',function(){
// stuff
});
// remove the listener
$(document).off("click", ".element");
To remove ALL event-handlers, this is what worked for me:
To remove all event handlers mean to have the plain HTML structure without all the event handlers attached to the element and its child nodes. To do this, jQuery's clone() helped.
var original, clone;
// element with id my-div and its child nodes have some event-handlers
original = $('#my-div');
clone = original.clone();
//
original.replaceWith(clone);
With this, we'll have the clone in place of the original with no event-handlers on it.
Good Luck...
Updated for 2014
Using the latest version of jQuery, you're now able to unbind all events on a namespace by simply doing $( "#foo" ).off( ".myNamespace" );
Best way to remove inline onclick event is $(element).prop('onclick', null);
Thanks for the information. very helpful i used it for locking page interaction while in edit mode by another user. I used it in conjunction with ajaxComplete. Not necesarily the same behavior but somewhat similar.
function userPageLock(){
$("body").bind("ajaxComplete.lockpage", function(){
$("body").unbind("ajaxComplete.lockpage");
executePageLock();
});
};
function executePageLock(){
//do something
}
In case .on() method was previously used with particular selector, like in the following example:
$('body').on('click', '.dynamicTarget', function () {
// Code goes here
});
Both unbind() and .off() methods are not going to work.
However, .undelegate() method could be used to completely remove handler from the event for all elements which match the current selector:
$("body").undelegate(".dynamicTarget", "click")
I know this comes in late, but why not use plain JS to remove the event?
var myElement = document.getElementById("your_ID");
myElement.onclick = null;
or, if you use a named function as an event handler:
function eh(event){...}
var myElement = document.getElementById("your_ID");
myElement.addEventListener("click",eh); // add event handler
myElement.removeEventListener("click",eh); //remove it
This also works fine .Simple and easy.see http://jsfiddle.net/uZc8w/570/
$('#myimage').removeAttr("click");
if you set the onclick via html you need to removeAttr ($(this).removeAttr('onclick'))
if you set it via jquery (as the after the first click in my examples above) then you need to unbind($(this).unbind('click'))
All the approaches described did not work for me because I was adding the click event with on() to the document where the element was created at run-time:
$(document).on("click", ".button", function() {
doSomething();
});
My workaround:
As I could not unbind the ".button" class I just assigned another class to the button that had the same CSS styles. By doing so the live/on-event-handler ignored the click finally:
// prevent another click on the button by assigning another class
$(".button").attr("class","buttonOff");
Hope that helps.
Hope my below code explains all.
HTML:
(function($){
$("#btn_add").on("click",function(){
$("#btn_click").on("click",added_handler);
alert("Added new handler to button 1");
});
$("#btn_remove").on("click",function(){
$("#btn_click").off("click",added_handler);
alert("Removed new handler to button 1");
});
function fixed_handler(){
alert("Fixed handler");
}
function added_handler(){
alert("new handler");
}
$("#btn_click").on("click",fixed_handler);
$("#btn_fixed").on("click",fixed_handler);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn_click">Button 1</button>
<button id="btn_add">Add Handler</button>
<button id="btn_remove">Remove Handler</button>
<button id="btn_fixed">Fixed Handler</button>
I had an interesting case relevant to this come up at work today where there was a scroll event handler for $(window).
// TO ELIMINATE THE RE-SELECTION AND
// RE-CREATION OF THE SAME OBJECT REDUNDANTLY IN THE FOLLOWING SNIPPETS
let $window = $(window);
$window.on('scroll', function() { .... });
But, to revoke that event handler, we can't just use
$window.off('scroll');
because there are likely other scroll event handlers on this very common target, and I'm not interested in hosing that other functionality (known or unknown) by turning off all of the scroll handlers.
My solution was to first abstract the handler functionality into a named function, and use that in the event listener setup.
function handleScrollingForXYZ() { ...... }
$window.on('scroll', handleScrollingForXYZ);
And then, conditionally, when we need to revoke that, I did this:
$window.off('scroll', $window, handleScrollingForXYZ);
The janky part is the 2nd parameter, which is redundantly selecting the original selector. But, the jquery documentation for .off() only provides one method signature for specifying the handler to remove, which requires this middle parameter to be
A selector which should match the one originally passed to .on() when attaching event handlers.
I haven't ventured to test it out with a null or '' as the 2nd parameter, but perhaps the redundant $window isn't necessary.
I am trying to have a change method for all visible select elements.
$('.select_elements:visible').change(function() {
// function
)};
The above doesn't seem to run when I change the select element. However if I write this it seems to work.
$('.select_elements').change(function() {
if ($(this).is(':visible')) {
// function
}
)};
Can anyone explain this? It wasted years (hours) of my life...
The difference is that the first version, where :visible is in the selector, only attaches the change event handler to the select elements that are visible in the DOM when the page loads.
The latter version attaches the event handler to all select elements, then checks their visibility at the time the event was fired.
Rory McCrossan's answer is an excellent explanation of what is happening. I am answering as well to propose a more performant and (to my mind at least) idiomatic solution than checking the visibility of elements in your change handler.
$(document).on('change', '.select_elements:visible', function () {
// ...
});
This approach attaches only a single change handler to the document (you could pass it any parent of your .select_elements), which fires whenever the element that is changed matches the selector in the second argument. Since that selector is evaluated for every change event, it will also fire for visible elements that weren't visible when the handler was defined.
This question already has answers here:
jQuery .on() method doesn't see new elements
(5 answers)
Closed 8 years ago.
I am using Jquery 2.1.0. I have injected some elements to the DOM (containing label) into a div element. I am using the following JavaScript to handle click event on all labels but it is completely dead and not responding. I checked and Jquery is loaded.
$('label').on("click", function () {
var ul = $(this).parent().children("ul:first");
if (ul.is(':visible')) {
ul.css({ "display": "none" });
}
else {
ul.css({ "display": "block" });
}
});
I used developer tools in IE 10 and debugged the code. When I hit F5 it goes to my break point (on first line of my code) but when I click a label nothing happens and no errors.
This will only assign the event handler to label elements which exist initially on the page:
$('label').on("click", function () {
// ...
});
To catch elements which are added later, you need to assign the event handler to a common parent element (which isn't added/removed during the life of the page) and filter the source elements, like this:
$(document).on('click', 'label', function () {
// ...
});
Note that there are two selectors:
document
'label'
The first, which is the target of the event handler, is only evaluated once when the page loads (or when this line of code is evaluated, which is generally when the page loads). This attaches the handler to the document object. Since all events "bubble up" to parent elements, this will catch all click events on the page (unless propagation is explicitly stopped, of course).
The second, which is the "filter" for the .on() method's handler, is evaluated any time an event is caught by this handler. It filters out the elements which originated the click event so that the handler is executed only for those which match the filter.
I've actually recently blogged about this very subject.
You need to use event delegation since your label has been dynamically created element:
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all children matching a selector,
whether those children exist now or are added in the future.
$('body').on('click','label', function() {
// Your code here
});
Basically, event delegation will helps you to attach click event to newly added label elements in your case
you should use event delegation for that
$(document).on("click","label",function(){
});
Event delegation allows you to attach a single event listener, to a parent element, that will fire for all children matching a selector, whether those children exist now or are added in the future.
From this answer to another question here: https://stackoverflow.com/a/8337382/2407870
It seems that the method doesn't work for some inline elements in Chrome. If your element is inline, try changing the display to block.
I am a bit confused, I have a bunch of elements that get added via jquery using a ajax call and I want to attach a click handler to them (there could be a lot).
But I have no idea how to even begin this, I looked at .on and it is really confusing. I want to attach a click event handler for a certain class so that when I click on it, I get the this.id and then do stuff with it.
What you're trying to do is called event delegation.
You want to set the event listener on a higher element in the DOM that'll never change, but only fire off the event handler if the child element that has been clicked matches a specific selector.
Here's how it's done with jQuery's .on():
$(document).on('click', '.your-selector', function(){
alert(this.id);
});
P.S. You could probably apply the event listener to an element lower down in the DOM tree...
This will get you the id of a clicked element with the class "test"...
$(".test").on("click", function() {
var id = $(this).attr("id")
});
You'll need to run that after the ajax call returns. It will only bind the click event to elements that exist when it runs, so it's no good at document.ready.