I have the following jQuery code:
$(document).on('focusout', '#element', function(e){
alert('test');
});
$(document).on('click', '#element_b', function(e){
$(document).off('focusout','#element');
/* do other stuff */
$(document).on('focusout','#element',function(){});
});
On clicking on #element_b, the event bound to #element is supposed to get off and then back on but for some reason after it goes off, it doesn't return back on. How to get it back on?
In order to be able to re-bind a handler, the handler function must be available for reference at the point it would be re-bound. To achieve that, just define the handler function with a name:
function focusOutHandler(e) {
alert("test");
}
$(document).on("focusout", "#element", focusOutHandler);
Then you can also reference the function in your "click" handler:
$(document).on('click', '#element_b', function(e){
$(document).off('focusout','#element');
/* do other stuff */
$(document).on('focusout', '#element', focusOutHandler);
});
Now, that said, that operation really doesn't make a lot of sense in the context of your question. While the "click" handler code is running, the "focusout" code will not run anyway. Thus, removing the handler at the start of the code and then adding it back at the end won't have any noticeable effect.
I would personally argue for a different approach so you can stop modifying the bindings. Instead change your matcher so it is more restrictive.
$(document).on('focusout', '#element:not(.restricted)', function(e){
alert('test');
});
If you made the selector like this, all you would have to do to "toggle" it on or off is add/remove the restricted class to the element, or whatever more restrictive matcher you give the delegate.
Related
I was wondering why this code would be effective, and if it is not, is there a better way to make sure that event handlers are removed before the new event handler is attached:
$('.selector')
.off('click', '.item')
.on('click', '.item', function() {
// code goes here
})
Thank you for help in knowing if this is an optimal way to make sure the event handler has been removed before adding another to the selector.
You can create a jQuery function that calls this two functions at once:
$.fn.onAndOff = function(event, selector, handler) {
this.off(event, selector)
.on(event, selector, handler);
}
Then use it like this:
$(".selector").onAndOff("click", ".item", function() {
// code goes here
});
If there's a risk of multiple identical click events being created for a particular element in your app, this may be a solution. Typically, however, the logic of your application is designed to prevent that.
JSFIDDLE: http://jsfiddle.net/w55usyqk/
When you click the div there are two separate click events fired. They print out "click" and "clicked" respectively in the console log.
$("div").on("click", function() { console.log("click"); });
$("div").on("click", function() { console.log("clicked"); });
If you tap on the button it will remove both event declarations from the div object
$("button").on("click", function() { $("div").off("click"); });
However, what if I just needed to remove a single click event? Is this stored in some sort of event array where I could do something along the lines of $("div").off("click")[1]; or is it impossible to turn off one without turning off the other as well?
I did try looking for the answer if it's been posted before. I think this is one of those questions that's hard to word, so though there may be an answer out there, it's difficult to pin down.
You can use namespaces to easily do this. When you create your event handlers, add the namespace after the event. Ex:
$("div").on("click.namespace1", function() { console.log("click"); });
$("div").on("click.namespace2", function() { console.log("clicked"); });
then for your button, use the namespace of the event to remove:
// remove only the event for namespace2
$("button").on("click", function() { $("div").off(".namespace2"); });
jsFiddle example
Some more on namespaces for events:
An event name can be qualified by event namespaces that simplify
removing or triggering the event. For example, "click.myPlugin.simple"
defines both the myPlugin and simple namespaces for this particular
click event. A click event handler attached via that string could be
removed with .off("click.myPlugin") or .off("click.simple") without
disturbing other click handlers attached to the elements. Namespaces
are similar to CSS classes in that they are not hierarchical; only one
name needs to match. Namespaces beginning with an underscore are
reserved for jQuery's use.
Use named functions as event handlers, so you can then reference what handler you want to unbind:
function clicOne() {console.log("click");};
function clicTwo() {console.log("clicked");};
$("div").on("click", clickOne);
$("div").on("click", clicTwo);
$("button").on("click", function() { $("div").off("click", clickOne); });
Is there a way that I can call $(selector).bind('click', handler) or $(selector).on('click', handler) multiple times such that the handler only gets attached once?
Right now, I have multiple AJAX handlers with different success callbacks, each of which re-renders a different set of elements on the page. Ideally I'd like to refactor the "reattach events" routine to a single function rather than a routine for all.
The only way I can think of to do this right now is to explicitly unbind, for example:
$(selector).off('click');
$(selector).on('click', handler);
Looking for a way to do something like that automatically.
A better approach is just to move the .on call to a container. If you have a container, the .on sticks around and is applied to any existing or new children matching your selector:
$(container-selector).on("click", "element-selector", function(event){
// do stuff
});
http://api.jquery.com/on/
Cheers.
You can namespace your event handlers, and then just make sure you unbind before binding:
$('#something').unbind("click.some-feature").bind("click.some-feature", function() { ... });
You could write your own jQuery function to do that automatically:
$.fn.schneiderBind = function(name, fn) {
return this.unbind(name).bind(name, fn);
});
$('#something').schneiderBind("click", function() { ... });
Alternatively, you can use bubbling and delegation to bind higher in the DOM, at a point immune to dynamic updates.
$(document).on("click","selector", function() { code goes here... });
This will work with dynamically added objects
On keyup my script does something, I was wondering if I could turn it off, as in, I only want it to check one key up.
ckEditorNewsArticle.document.on("keyup", function(){
Edit:
ckEditorNewsArticle.document.on('keyup', function(){
alert('key up');
});
This works. But I cant get it to fire only once, by using one.
ckEditorNewsArticle.document.one('keyup', function(){
alert('one');
});
You can turn off events using (surprise, surprise), .off().
ckEditorNewsArticle.document.off('keyup');
If you want a handler to run only once though, might I suggest using .one()?
ckEditorNewsArticle.document.one('keyup', function () {
// do something
});
use .one():
Attach a handler to an event for the elements. The handler is executed
at most once per element.
Documentation: http://api.jquery.com/one/
Working example: http://jsfiddle.net/54ymc/
I would like to set an attribute for a div. I have done this:
$('#row-img_1').onmouseover = function (){ alert('foo'); };
$('#row-img_2').onmouseout = function (){ alert('foo2'); };
However, the above has not worked, it does not alert when mouse is over or when it moves out.
I have also tried the $('#row-img_1').attr(); and I could not get this to work either.
I am aware that I should be using a more effective event handling system but my divs are dynamically generated. Plus this is a small project. ;)
Thanks all for any help.
You need to bind the event function to the element. Setting the event attributes has no effect, as they are interpreted only when the page is loading. Therefore, you need to connect the event callback in a different manner:
$('#row-img_1').mouseover(function() {
alert('foo');
});
$('#row-img_2').mouseout(function() {
alert('foo2');
});
In jQuery, there are two more events: mouseenter and mouseleave. These are similar, but mouseenter does not fire upon moving the mouse from a child element to the main element, whereas mouseover will fire the event again. The same logic applies to mouseleave vs mouseout.
However, jquery provides a shortcut for this kind of usage: the .hover method.
$('#row-img_1').bind('mouseenter', function(event){
// event handler for mouseenter
});
$('#row-img_1').bind('mouseleave', function(event){
// event handler for mouseleave
});
or use jQuerys hover event which effectivly does the same
$('#row-img_1').hover(function(){
// event handler for mouseenter
}, function(){
// event handler for mouseleave
});
Events are registered as functions passed as attributes, like this:
$('#row-img_1').mouseover(function (){ alert('foo'); });
$('#row-img_2').mouseout(function (){ alert('foo2'); });
Also, note the missing on from the onmouseover.
$('#row-img_1').mouseover(function() {
alert('foo');
});