Remove all the events attached to an element except one - javascript

How may I remove all the events attached to a DOM element except one using jquery?
For example, I have a drop down <select> and it has various events attached to it (say click, double click, change etc). What I want to achieve is to just have change event applied to it and remove all the other events. How may I achieve this?
P.S I don't know about the events attached to the element

$( "#foo").unbind( "click" );
Fill in the rest. http://api.jquery.com/unbind/

May be you can use something like:
$.(selector).on('*',function(e)
{
if(e.which='value_for_your_event_eg._14_for_tab')
return true;
else
return false;
})
I don't know, I'm not an expert, but I guess this would work.

$._data(elem,'events') is not a method publicly supported:
DEMO
$.each($._data($('select').get(0),'events'),function(k){
if(k !== "change")
delete $._data($('select').get(0),'events')[k];
});

$( "#foo").off();
Will remove all events attached to foo element
You can also do:
$( "#foo").off("click dblclick");
you can then attach on foo element only onchange event
$("#foo").on("change",function(){
//Do stuff here
})

Related

jQuery remove scroll listener after reach certain point [duplicate]

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.

How to get which element was clicked?

I have a simple div in my html as follows:
<div id="myDiv">
....
</div>
Also I have set the onlick event on the window.click as follows:
window.onclick = function()
{
// do something
}
So if I click, anywhere in the div, how can I find that this click was made inside "myDiv"
Note : I cannot add the click event on my div, it is generated randomly from jqgrid
$(document).on("click","#myDiv", function (event) {
alert(event.target.id);
});
The aim of the question is simply this. "I wish to know when a dynamically added div is clicked". The moment you see dynamically added think delegated events! :)
As this question allows for jQuery, the answer by #erkaner is close to ideal for this situation. I just wish to explain why it is the appropriate solution.
$(document).on("click","#myDiv", function (event) {
// Do something
});
Explanation:
This uses a jQuery delegated event handler. The event handling is "delegated" to a non-changing ancestor of the intended target, hence the name.
The chosen ancestor is document in this case.
You should use the closest non-changing ancestor to the target, but document is the best default if nothing else is closer/convenient.
Warning: Do not use body for delegated events as it has a bug (styling can cause it to not get bubbled mouse events).
The event (click in this case) bubbles up to the handler element (i.e. document).
The jQuery selector (in this case #myDiv) is then applied to just the elements in the bubble-chain. This is very efficient.
The supplied handler function is then just applied to any matching elements that caused the event.
The upshot of all this is that the element need not exist until event time (it does not need to exist when the event was registered).
Further, because delegation is typically used on mouse events (and not 50,000 times a second) any speed difference between this and a "raw" event handler is negligible. The benefits far outweigh any trivial speed difference.
Regarding the other onclick= answers
Firstly, using the single window.onclick property is a bad idea as you stop anything else using it (not that anyone using jQuery should use it).
Secondly the event parameter passed to onclick is not provided by all browsers (this should be enough to stop anyone using it). There are workarounds, but jQuery was created to avoid browser workarounds :)
Notes:
If the naming is not under your control, you just need something to match on. Worst case, it could be as simple as "match any div under any table", but that will depend on your specific HTML & code:
$(document).on("click","table div", function (event) {
// Do something
});
Here is a practical example:
http://jsfiddle.net/TrueBlueAussie/eyo5Lnsy/
Get the event from the function: window.onclick = function(event) then inside the function you can use it as event.target:
window.onclick = function(event)
{
alert(event.target);
}
Here's an example using addEventListener - without using jQuery
document.getElementById('myDiv').addEventListener('click',function(e){
// this div has been clicked
console.log('this div has been clicked');
});
UPDATE
Here's the non-jQuery solution for dynamically created elements
document.addEventListener('click',function(e){
if( e.target.id == 'myDiv' )
{
// this div has been clicked
console.log('this div has been clicked');
}
});
var myDiv = document.getElementById('myDiv');
myDiv.style.cursor = 'pointer';
myDiv.onclick = function() {
//DO SOMETHING
};
Here we go.
$('body').click(function(e) {
if (e.target.id == 'myDiv') {
alert('My Div!!!!');
}
});​
$( "body" ).click(function( event ) {
$( "#log" ).html( "clicked: " + event.target.nodeName );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myDiv">
....
</div>
<div id="log"></div>
check below code. check DEMO
use event.target to get clicked element .
window.onclick = function(event)
{
if(event.target.id == "myDiv"){
alert("here")
}else{
alert('Body')
}
console.log(event.target.id)
}

Is there a way to get all default_event_actions, then prevent some except others with event.preventDefault() in jQuery?

I'd like to know if is there a way to have a list of the default_event_actions for a particular element that 'event.preventDefault()' has been applied on and tell the script what event or action to prevent or not...
something like:
$(element).on('click', function(e){
e.preventDefault() //this will prevent all
//...is there a way of preventing specifically or particularly...
})
Is it possible?
You can use e.type to check type of event and based on condition can prevent default for example:
$(element).on('click', function(e){
if(e.type == 'click')
e.preventDefault(); //this will prevent all
}
});
You can use jQuery event namespaces to give unique name to your events : event.namespace
And to find all events attached to a particular element, you can look at Jonathan Sampson's answer for this question (Can I find events bound on an element with jQuery?)

JavaScript: capturing events regardless of element

Is there any existing mechanism by which I can add an event listener to 'focus' for all the DOM elements on the page that have this event? If not, how might I do that?
I'd like to console.log(something) any time any DOM element fires an event. How might I do this?
EDIT: Without any framework please :)
You can bind the event to the body or html element. Or any other element which encloses all of your html.
Or if you want to use jQuery you could do something like
$("*").bind("focus", function(e){
console.log("something");
})
Events "bubble" up through the DOM, so you should be able to bind a listener to document, body, html, or any other parent element (e.g. a div) and listen for every event triggered by elements that it contains.
For example, using JQuery, you could do it like this:
$(document).bind('focus', function(e) { console.log(e); });
This will log every focus event, no matter what element initially triggers the event.
You could try using the :input pseudo selector in jQuery.
$(':input').focus(function(e){
console.log(e);
});
This will only attach to the input elements which is probably what you're looking for anyway.
Something like this should work (with jQuery).
$("input").focus(function(){
console.log($(this).attr("id"));
});
Here's a live example:
http://jsbin.com/ipiciz/edit#javascript,html,live

How to bind to all click events, check for an attribute.... Efficiently?

I want to create a binding that captures all click events. And then if the item clicked has a "data-track" attribute do something...
What is the efficient way to do this? Can I bind at the body and let all the events bubble up. Any suggestions on how and how to do this efficiently?
Thanks
You should aim for simplicity over performance: Let jQuery do the work for you, and assume that the jQuery devs are better at optimizing JS than you unless you can prove otherwise.
Use the has attribute jQuery selector to setup a live click handler for all elements with the data-track attribute:
$('[data-track]').live('click', function () {
});
Attach click event handler at the document level using delegate with attribute selector [data-track].
$(document).delegate('[data-track]', 'click', function(){
//Do something here
});
Why don't you bind click events to ONLY items with a data-track attribute?
$('[data-track]').click(function() {
var data_track = $(this).attr('data-track');
//code here
});
I would go like this:
$('*[data-track]').click(function(ev){
// do something
});
or (if some such content coming from Ajax)
$('*[data-track]').live('click', function(ev){
// do something
});
Do you have to capture all click events? If you're only doing something if it has a "data-track" attribute, I believe you should be able to do:
$("*[data-track]").click(function(){//do something});
I'm not sure how that compares to other methods though for efficiency, although I think that since jQuery captures all events at the window level, it shouldn't make a difference.

Categories