I've a bad-programmed library which is doing this
$(document).on('click','#keep_first_only_button', function(){
I wrote, after this, a piece of code to 'override' this bad behaviour
$("keep_first_only_button").unbind("click");
$("keep_first_only_button").on("click", selectKeepFirstOfAll);
BUT this is not working, then document.click function handler is triggered again
I cannot unbind all click events from document, because disasters will happen in the page.
Which is the right way to proceed in this situation?
EDIT: Sorry for time loosing question, I didn't see the missing '#' in my selector. I'm really sorry !
The original event handler was bound as a delegated event, so you can't remove it from $('#keep_first_only_button') itself. You need to remove it on the document level.
From the documentation:
To remove specific delegated event handlers, provide a selector
argument. The selector string must exactly match the one passed to
.on() when the event handler was attached. To remove all delegated
events from an element without removing non-delegated events, use the
special value "**".
In other words, to unbind a delegated event, you should just use the same set of arguments you used to bind them but pass them to off instead. Since the bound function is anonymous you can't reference it, so you'll have to settle with unbinding all delegated event handlers bound to #keep_first_only_button on the document level:
$(document).off('click', '#keep_first_only_button');
EDIT: Looks like the problem was just the missing hash. Odd, I thought you couldn't unbind delegated event handlers using a regular .off() call...
$("#keep_first_only_button")...
Missing the hash?
For anyone wondering ...Mattias Buelens is correct.
If you have the element bound like
$(document).on("click","#element",function(){ });
And want to shut it off later, you have to do it as:
$("#element").click(function(e) {
$(document).off('click', '#element');
});
If you want remove event with out consider selector use
$(document).off("click","**");
Related
I have a question about the binding and unbinding events to elements in Javascript. I understand this: we bind and unbind elements to a elements when we create an element and this do something so we bind an event and when the user delete this element with and action the event listener needs to be remove because the element was removed, this is was I think, so my question is I am correct? Or when and why we bind and unbind events.
Thanks.
The reasons of when and why to bind an event are too numerous to list here (probably the former is more broad than the latter).
However, 'we' as programmers use functions such as bind() so that our code may listen to events that occur on a particular element.
unbind() is used when we no longer need to receive callbacks that an element has received such an event.
As to when we use bind() and unbind() depends entirely upon the project and requirements for the event. Sometimes the events will be bound upon the creation of an element. Sometimes they'll be bound by a trigger (such as a user clicking a widget, for example), and sometimes they will be bound by the response of an AJAX call (or similar server-side callback). Similarly, we may use unbind() inside of a callback from another event, or when something happens on the server.
As you can see, there is no "definitive" answer to when we use bind() and unbind(). However, you're slightly incorrect in your statement that unbind() is used when an element is removed. That is not necessary, when the element is removed, its event bindings are automatically discarded.
Let's say we have this span:
<span id="my-span">Hello.</span>
I want to be notified when a click occurs:
var span = document.getElementById('my-span');
var alertWhenMySpanIsClicked = function () {
alert('my span was clicked');
};
span.addEventListener(
'click', alertWhenMySpanIsClicked
);
I don't want to be notified anymore:
span.removeEventListener(
'click', alertWhenMySpanIsClicked
);
I have this:
$(function(){
//remove keydown doSomething2
$("body").keydown(doSomething1);
});
In other view I have this:
$(function(){
//remove keydown doSomething1
$("body").keydown(doSomething2);
});
How to do what's in the comment? With my current code, both doSomething1 and doSomething2 are called. I want do disabled the one I dont need.
To remove an event listener with jQuery, you can use .off():
$("body").off("keydown", doSomething2);
Remember the keydown method is just a shortcut for .on("keydown", ...).
However, to "disable" them it might be easier to have only one handler that executes different things based on the current selected view, or have both of them bound and each with a short check that the right view is currently selected.
If doSomething2 is a function reference, you can use .off() (jQuery 1.7+) or .unbind() to remove jQuery bound event handlers:
$('body').off('keydown', doSomething2);
// or
$('body').unbind('keydown', doSomething2);
Note that execution order will be a factor. If the code to unbind the event handler is run first it will have no effect. In general, jQuery event handlers are triggered in the order they're bound, so if the first code snippet in your question is executed first, this approach won't work (you'll need to re-order it).
try this as below using jQuery:
$(function(){
// this would remove keydown from body
$("body").unbind('keydown', doSomething2);
});
I am using jQuery v.1.7.1 where the .live() method is apparently deprecated.
The problem I am having is that when dynamically loading html into an element using:
$('#parent').load("http://...");
If I try and add a click event afterwards it does not register the event using either of these methods:
$('#parent').click(function() ...);
or
// according to documentation this should be used instead of .live()
$('#child').on('click', function() ...);
What is the correct way to achieve this functionality? It only seems to work with .live() for me, but I shouldn't be using that method. Note that #child is a dynamically loaded element.
Thanks.
If you want the click handler to work for an element that gets loaded dynamically, then you set the event handler on a parent object (that does not get loaded dynamically) and give it a selector that matches your dynamic object like this:
$('#parent').on("click", "#child", function() {});
The event handler will be attached to the #parent object and anytime a click event bubbles up to it that originated on #child, it will fire your click handler. This is called delegated event handling (the event handling is delegated to a parent object).
It's done this way because you can attach the event to the #parent object even when the #child object does not exist yet, but when it later exists and gets clicked on, the click event will bubble up to the #parent object, it will see that it originated on #child and there is an event handler for a click on #child and fire your event.
Try this:
$('#parent').on('click', '#child', function() {
// Code
});
From the $.on() documentation:
Event handlers are bound only to the currently selected elements; they
must exist on the page at the time your code makes the call to .on().
Your #child element doesn't exist when you call $.on() on it, so the event isn't bound (unlike $.live()). #parent, however, does exist, so binding the event to that is fine.
The second argument in my code above acts as a 'filter' to only trigger if the event bubbled up to #parent from #child.
$(document).on('click', '.selector', function() { /* do stuff */ });
EDIT: I'm providing a bit more information on how this works, because... words.
With this example, you are placing a listener on the entire document.
When you click on any element(s) matching .selector, the event bubbles up to the main document -- so long as there's no other listeners that call event.stopPropagation() method -- which would top the bubbling of an event to parent elements.
Instead of binding to a specific element or set of elements, you are listening for any events coming from elements that match the specified selector. This means you can create one listener, one time, that will automatically match currently existing elements as well as any dynamically added elements.
This is smart for a few reasons, including performance and memory utilization (in large scale applications)
EDIT:
Obviously, the closest parent element you can listen on is better, and you can use any element in place of document as long as the children you want to monitor events for are within that parent element... but that really does not have anything to do with the question.
The equivalent of .live() in 1.7 looks like this:
$(document).on('click', '#child', function() ...);
Basically, watch the document for click events and filter them for #child.
I know it's a little late for an answer, but I've created a polyfill for the .live() method. I've tested it in jQuery 1.11, and it seems to work pretty well. I know that we're supposed to implement the .on() method wherever possible, but in big projects, where it's not possible to convert all .live() calls to the equivalent .on() calls for whatever reason, the following might work:
if(jQuery && !jQuery.fn.live) {
jQuery.fn.live = function(evt, func) {
$('body').on(evt, this.selector, func);
}
}
Just include it after you load jQuery and before you call live().
.on() is for jQuery version 1.7 and above. If you have an older version, use this:
$("#SomeId").live("click",function(){
//do stuff;
});
I used 'live' in my project but one of my friend suggested that i should use 'on' instead of live.
And when i tried to use that i experienced a problem like you had.
On my pages i create buttons table rows and many dom stuff dynamically. but when i use on the magic disappeared.
The other solutions like use it like a child just calls your functions every time on every click.
But i find a way to make it happen again and here is the solution.
Write your code as:
function caller(){
$('.ObjectYouWntToCall').on("click", function() {...magic...});
}
Call caller(); after you create your object in the page like this.
$('<dom class="ObjectYouWntToCall">bla... bla...<dom>').appendTo("#whereeveryouwant");
caller();
By this way your function is called when it is supposed to not every click on the page.
this code in book jQuery in action page 131
i don't understand
.trigger('adjustName');
what is adjustName
and Simple explanation for trigger()
thanks :)
$('#addFilterButton').click( function() {
var filterItem = $('<div>')
.addClass('filterItem')
.appendTo('#filterPane')
.data('suffix','.' + (filterCount++));
$('div.template.filterChooser')
.children().clone().appendTo(filterItem)
.trigger('adjustName');
});
It is a string, the name of a custom event you defined.
E.g. it would trigger the event handler bound by:
el.bind('adjustName', function(){...});
For more information I suggest to have a look at the documentation:
Any event handlers attached with .bind() or one of its shortcut methods are triggered when the corresponding event occurs. They can be fired manually, however, with the .trigger() method. A call to .trigger() executes the handlers in the same order they would be if the event were triggered naturally by the user.
Without knowing the context of the code, I would say that calling .trigger() here has no effect, as it is called on the cloneed elements and the event handlers are only cloned if true is passed to clone.
Maybe the original jQuery manual could be helpful?
Description: Execute all handlers and
behaviors attached to the matched
elements for the given event type.
It allows you to trigger, or run, an event. For instance if you wanted the code to mimic the clicking of a button, you could write....
$("#myButton").trigger('click');
This would then run exactly as if you had clicked the button yourself.
'adjustName' is a custom event. So the trigger function is running that custom event. The custom event is assigned using the jQuery bind function.
$("#someElement").bind('adjustName', function() {/* Some Code */});
You might create a customer event for clarity. Perhaps your application opens a document, so you might want an event called 'openDocument' and 'closeDocument' assigned to the element containing the document.
What does bind and unbind mean in jquery in idiot slow learner terms?
Binding: coupling an handler to an element(s), that will run when an event occurs on said element(s). Depending on what kind of event you want to handle you'd use different functions like click(function) (alt: bind('click', function) or focus(function) (alt: bind('focus', function).
Unbinding: de-coupling of an handler from an element(s), so that when an event occurs the handler function will no longer run. Unbinding is always the same; unbind('click', function) to unbind a certain handler, unbind('click') to unbind ALL click handlers, and unbind() to unbind ALL handlers. You can substitute click for other types of events of course.
In simple terms: for binding and unbinding event handlers to elements.
$("#divElement").bind('click', functionName);
binds a click event handler to the element with id divElement
$("#divElement").unbind('click', functionName);
unbinds a click event handler to the element with id divElement
Edit:
Bind also allows you to bind a handler to one or more events.
$("#divElement").bind("click dblclick mouseout", function(){ // your code });
Update:
As of jQuery 1.7, the .on() and .off() methods are preferred to attach and remove event handlers on elements.
In three sentences:
An event is a signal that is visible in your program - a key press, for example.
A handler is a function that is geared towards reacting to a certain event.
Binding associates a handler with an event, unbinding does the opposite.
Bind attaches a piece of code to be run to a given HTML element (which is run on the supplied event). unbind removes it.