jQuery .off() not removing handlers - javascript

I have a dynamically loaded button created when the document loads. After this, I attach a click handler to this button. When I try to remove the handler with .off(), it does not work.
This snippet creates the click handler and removes it. However, when I click the button, the function StartMash still executes.
$(document).on("click", "#mash-idle-start", StartMash);
$("#mash-idle-start").off();
Obviously this is not the functionality I am trying to achieve, but the problem persists through this simple example

because the event handler is not attached to #mash-idle-start, it is attached to document so
$(document).off("click", "#mash-idle-start", StartMash);
or
$(document).off("click", "#mash-idle-start");
Note: When working with event unbinding, try to use event namespaces as you will have more control over which handlers are removed.

Related

Catching click event while delete thumbnail

I slightly modified FU thumbnail template to hook a click event on it. I also display a delete button (the provided one).
The problem is that when I click on the delete button, the click event bubbles to the rest of the javascript stack.
How can I prevent the delete button to propagate the click event??
(usually you do something like event.stopPropagation()...).
Thanks for your help
If you'd like to prevent any DOM event from bubbling, simply attach an event handler to the element where you would like it to terminate and call stopPropagation() on the Event object. For example, for a click event:
someElement.addEventListener('click', function(event) {
event.stopPropagation();
});
The above code will not work in IE8 and older since addEventListener and stopPropagation were first introduced in IE9.

Need to get info from any element, which was clicked, but not from parent elements

Need to get info from any element, which was clicked.
Example:
<div>text1<section>text2</section></div>
and JS
$(function(){
$('body *').click(function(){
alert($(this).get(0).tagName.toLowerCase());
});
});
If I click text2, parent element throw alert too. I need only first alert from section. How I can block next alerts from all parent elements of section.
Use event.stopPropagation() to prevent the event from firing on the containing elements.
$(function(){
$('body *').click(function(e){
e.stopPropagation();
alert($(this).get(0).tagName.toLowerCase());
});
});
Just wanted to expand on Kooilnc answer - Using on with event delegation is another option.
Event delegation would be nice if you have an event listener bound before or after on a node that needs to listen to a click handler that has bubbled up. If you stopPropagation, this obviously would be an issue.
Here's a fiddle with a demo:
http://jsfiddle.net/ahgtLjbn/
Let's say a buddy of yours has bound an event listener to a node higher up in the DOM tree. He expects any events that bubble up to it, to be handled by his script.
Using event delegation, the event still bubbles up (so your buddies code will still fire), but it will only alert once (since we called e.stopPropagation).
Calling on without event delegation, or binding the event directly using click (which, under the hood, is just calling on) will prevent the event from bubbling, so your buddies code will never run.

removeAttr('id') clears #id but still the clicks work

I have the <div id="SocialInteract">
$('#SocialInteract').click(function() {
$('#SocialCount').load('sc.php');
$('#TeacherAttendance').removeAttr('id');
});
When I view the InspectElement the #id is removed but it still takes the click. Something I am doing wrong?
Your click event still fires because the event is already attached to the TeacherAttendance element.
If you want to detach the click event, you should use off() or unbind() :
$('#TeacherAttendance').off('click');
$('#TeacherAttendance').unbind('click');
Removing id wont remove already attached click event. Use unbind() method to remove attached event.
$('#TeacherAttendance').unbind("click");
EDIT :
You should use off() as its the updated one. unbind() is still there for backword compatibility
$('#TeacherAttendance').off('click');
Related question : Best way to remove an event handler in jQuery?
You are binding to the DOM element the event, then you remove the id but the event it's already registered.
use off or unbind or set a global var to turnoff/remove/doNothing .
.click() just attaches and forgets. It doesn't care whether anything happens to that element.
So you've to manually unbind the event.
.unbind('click');
To make the event binding dynamic, attack it to the document and wait for it to bubble up:
$(document).on('click', #SocialInteract', function() {
$('#SocialCount').load('sc.php');
$('#TeacherAttendance').removeAttr('id');
});
This way the event is registered to the document node: if the click event was fired on an element that had that ID, it will trigger. If not, it won't.

How can I find out where a click event gets caught?

I am working on a very complex website and i have a piece of HTML on the page inside which no button is clickable. I think the click event gets caught somewhere so that the click handlers of the buttons do not fire.
How can I find out where those click events gets caught?
Add a click event listener to the document, and see what's catching the event:
document.addEventListener('click',function(e){
console.log(e.target);
})
Just check the event.target of the click event to see where it is.
There should be a document.click() or document.live("click",...) handler somewhere in the javascript included in the page, which returns false.

In jQuery, is there any way to only bind a click once?

I have an ajax app that will run functions on every interaction. I'd like to be able to run my setup function each time so all my setup code for that function remains encapsulated. However, binding elements more than once means that the handler will run more than once, which is obviously undesirable. Is there an elegant way in jQuery to call bind on an element more than once without the handler being called more than once?
User jQuery one function like Tom said, but unbind the handler each time before binding again. It helps to have the event handler assigned to a variable than using an anonymous function.
var handler = function(e) { // stuff };
$('#element').unbind('click', handler).one('click', handler);
//elsewhere
$('#element').unbind('click', handler).one('click', handler);
You can also do .unbind('click') to remove all click handlers attached to an element.
You could attach the event to document with the one() function:
$(document).one('click', function(e) {
// initialization here
});
Once run, this event handler is removed again so that it will not run again. However, if you need the initialization to run before the click event of some other element, we will have to think of something else. Using mousedown instead of click might work then, as the mousedown event is fired before the click event.
You can also use .off() if unbind doesn't do the trick. Make sure the selector and event given to .off exactly match the ones initially provided to .on():
$("div.selector").off("click", "a.another_selector");
$("div.selector").on("click", "a.another_selector", function(e){
This is what worked for me in resolving the same ajax reloading problem.
The answer from Chetan Sastry is what you want. Basically just call a $(element).unbind(event); before every event.
So if you have a function like loadAllButtonClicks() that contains all the
$(element).on("click", function (){});
methods for each button on your page, and you run that every time a button is clicked, this will obviously produce more than one event for each button. To solve this just add
$(element).unbind(event);
before every
$(element).on("click", function (){});
and it will unbind all events to that element, then add the one click event.

Categories