how to bind again the click event for the button - javascript

I have a button on which i am attaching a click event. I have to unbind it after i click on it, and later on in my code i need to bind that click event on it again. I tried binding it again but that does not works. I can't use jquery 'live'. Is there any way to create a custom bind function on click event and then again call it ?
$(".submitButton").click(function(e){
//some functionality on click
$(".submitButton").unbind('click');
});
//somewhere ahead in my code
$(".submitButton").bind('click');
Apparently this isn't working. Is there any way to tackle this ?

Your .bind call doesn't seem correct. You haven't specified a callback.
So start by writing a function:
function handleButtonClick() {
//some functionality on click
$(this).unbind('click');
}
Notice that inside the handler I am unbinding $(this) which is the element being clicked and not all elements with class="submitButton".
and then:
$('.submitButton').bind('click', handleButtonClick);
and then later when you want to rebind:
$('.submitButton').bind('click', handleButtonClick);
and so on.

define your listener somewhere else:
function clickHandler() {
//some functionality on click
$(".submitButton").unbind('click', clickHandler);
}
$(".submitButton").bind('click', clickHandler);
//somewhere ahead in my code
$(".submitButton").bind('click', clickHandler);

When you use .bind() to bind an event handler it expects a function to be passed as well, since that's what will be executed when the event fires. Don't use an anonymous function, instead declare a named function and pass a reference to that when binding.
function handleClick(e){
//some functionality on click
$(".submitButton").unbind('click');
}
$(".submitButton").click(handleClick);
// somewhere else in your code (in reaction to some other event)
$(".submitButton").click(handleClick);

You can use jQuery.one(). Please refer below code.
$(".submitButton").one('click', clickHandler);
The first form of this method is identical to .bind(), except that the handler is unbound after its first invocation.
you can call it or bind it whenever it necessary.

Related

Nested eventlistener how to bind on first invoke

I am trying to bind an event to a class selector that is loaded asynchronously. I am using a jQuery .on event listener so it will work asynchronously.
However as I am binding another event inside the eventlistener. This means I have to trigger the event twice to make the function run.
button.on("touchend", tapHandler);
function tapHandler()
button.swipe( {
//Generic swipe handler for all directions
tap:function() {
banner.toggleClass("alt")
}
});
});
Is there a way to immediately invoke the nested eventlistener on the first invocation?
This jsfiddle shows the problem clearly. When using a touch device, the button has to be pressed twice for the toggleClass to be invoked.
jsfiddle (use touch device in dev-tools)
Is there a way to immediately invoke the nested eventlistener on the first invocation?
If you mean "...when adding it" rather than "...on the first invocation", then yes, there are at least two ways:
Define a named function, use it in the handler, and call it directly:
function tapHandler() {
function swipeHandler() {
banner.toggleClass("alt")
}
button.swipe( {
//Generic swipe handler for all directions
tap: swipeHandler
});
swipeHandler();
});
That just calls swipeHandler once and doesn't pass it an event object; looking at what it does, that seems fine. A more thorough version might loop through button (since jQuery objects are sets).
Use trigger or triggerHandler:
function tapHandler() {
button.swipe( {
//Generic swipe handler for all directions
tap: function() {
banner.toggleClass("alt")
}
});
button.triggerHandler("tap");
});

jquery stop delegated event from being called twice

My JS looks something like this
$(document).ready(function(){
menuClickHandler();
});
I have ajax based menu, menuClickHandler is used to make it work and resides in a separate JS file. menuClickHandler associates other functions that are associated to menu item. On click of menu item it calls a function associated with the menu item. Lets say I have menu item Jump and a function JumpHandler associated with it. Within JumpHandler there is one simple function as follows
functionA() {
$("div.tree").on("click", ".branch", function(event) {
event.stopPropagation();
//some code
});
}
Scenario:
When the page is first loaded everything is fine, when I click on Jump functionA' gets called and everything works fine. Now if click some other menu item and then click onJumpagain,JumpHandleris called again and hencefunctionA` gets called again resulting in click event on branch being bound twice. Can anyone tell me how do I remove/undelegate the delegated click event so that there is only click event bound to branch.
jQuery version: v2.1.1
You can use .one() instead of .on()
Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
Code
$("div.tree").one("click", ".branch", function(event) {
event.stopPropagation();
//some code
});
if for some reason you have to bind click event inside functionA, then you can try off
functionA() {
$("div.tree").off("click", ".branch" );
$("div.tree").on("click", ".branch", function(event) {
event.stopPropagation();
//some code
});
}
or else you can do this binding outside the functionA since it is attach the event handlers to future branch elements regardless of when you invoke functionA
if you want to ensure that event is only fired once, then
functionA() {
$("div.tree").on("click", ".branch", function(event) {
event.stopPropagation();
//some code
$("div.tree").off("click", ".branch" );
});
}
Because Once the function is called you have initialize a function in jquery which will execute without calling the function again. So before calling any function just turn off the jquery function
example:
$("div.tree").off("click", ".branch" );
functionA();
$("div.tree").off("click", ".branch" );
functionB();

jquery .off doesn't seem to work

so I'll be short: jquery .off() doesn't disable a listen I've set with .on.
html:
<span id="myspan">lol</span>
<button id="b1">jquery On</button>
<button id="b2">jquery Off</button>
js:
$("#b1").on("click", add);
$("#b2").on("click", del);
function add() {
$("#myspan").on("click", function(e) {
var a = 1;
testfunc(a, e);
});
}
function del() {
$("#myspan").off("click", testfunc);
}
function testfunc(num, event) {
alert(num);
}
So first we add to myspan the testfunc() by clicking the jquery On button. After we do that, if we click on the span, we get an alert. Next, we click the jquery off button. That is supposed to remove the listener but it doesn't. Even after that, when we click on myspan testfunc is still attached.
Why? And how can I remove it ?
Your parameters don't match
It doesn't because you bound to a different function (anonymous one). And then you're trying to unbind from testfunc... In order for your event (un)binding to work both parameters between on and off must match.
Possible workaround
If this is the only click event listener on the element, then it's be easiest way to unbind from your anonymous function by calling:
$("#myspan").off("click");
If you're binding several event handlers to click event on the same element then you can also distinguish them by providing namespaces and then use proper namespacing in off call.
$("#myspan").on("click.test", function(e) { ... });
...
$("#myspan").off("click.test");
Or use just namespace if you'd like to unbind several different event handlers that were bound using the same namespace:
$("#myspan").off(".test");
You're not binding the event handler to testfunc, you're binding it to an anonymous function, and whitin that function you're just calling testfunc, so you can't automatically unbind that.
It's either
$("#myspan").on("click", testfunc); // bind function
and then
$("#myspan").off("click", testfunc); // unbind function
or to unbind the anonymous function, just
$("#myspan").off("click"); // remove all handlers
or you can also namespace the handler
$("#myspan").on("click.test", function(e) {
var a = 1;
testfunc(a, e);
});
and to remove only that handler
$("#myspan").off("click.test");
In this simple case, replace your off call with this:
function del() {
$("#myspan").off("click");
}
You don't need to pass the handler function to the off call, and if you do, it will only remove that particular handler. However, you did not attach testfunc, but an anonymous function that just calls testfunc(). Therefore, your off call does nothing.
Also, you never assigned the variable testfunc.

Separate Event Handler for Reusability

I have a simple click handler that will alert its link's href as in:
<a id="link" href="http://www.google.com">Google</a>
$('a#link').on('click', function() {
alert($(this).attr('href'));
});
How can I separate the function (and how to call it) so that it can be called by another click handler?
function showHref() {
/* What to do here because $(this) won't resolve to <a> anymore. */
}
// I'd like a#another-link to be able to call that same function above.
<a id="another-link" href="http://www.microsoft.com">Microsoft</a>
$('a#another-link').on('click', /* How to call showHref? */);
Thanks.
You could do something like this:
function showHref() {
alert($(this).attr('href'));
}
$('a#link').on('click', showHref);
$('a#another-link').on('click', showHref);
In this code, this inside the showHref will refer to the link being clicked, since jQuery makes sure that the link being clicked is the calling context (using .call() which you may want to read up on). If, however, you were to manually call showHref, this would not refer to your link.
If you want a definition of showHref that you could both call manually, and bind through jQuery, it would probably be neatest to pass the reference as a parameter:
function showHref(link) {
alert($(link).attr('href'));
}
In that case, you'd have to adjust your listeners as follows:
$('a#link').on('click', function() {
showHref(this);
});
But it is also possible to combine selectors:
$('a#link, a#another-link').on('click', function() {
alert($(this).attr('href'));
});
You can put the function logic into a reference like this:
var handler = function () {
alert($(this).attr('href'));
};
Then you can use that reference to initialize event listeners:
$('#link').on('click', handler);
Of course, you can reuse that.
$('#some_other_link').on('click', handler);
Or call that yourself outside of an event handler context (which normally wouldn't make sense if you're fashioning an event handler function --- but it can be done with lambdas in general).
handler();
But if you want to just trigger the event on an element, you should call the corresponding event trigger function.
$('#link').click();
// or
$('#link').trigger('click');
You wrote:
function showHref() {
/* What to do here because $(this) won't resolve to <a> anymore. */
}
Umm, actually, yes it will. That's exactly the promise made by DOM events and also event handlers registered with jQuery.
FWIW, the content should just be:
alert(this.href)
There's really no need to invoke jQuery just to get the element's href attribute.

Cancel jQuery event handling

I have setup onclick event handler in the following manner:
element.onclick = function() { /*code */ }
Imagine there are event handlers setup using jQuery method bind() or similar handlers.
$('element').bind('click', function(){/*another function*/})
How can I prevent invoking handler defined with jQuery from the handler I have described in the beginning?
NB stopPropagation() and etc. jQuery's methods doesn't work from that function, because it is passed with native event object.
I'm not 100% sure what you're asking but maybe this will help:
You can create a new event object (compliant with W3C DOM) via jQuery's exposed Event constructor:
For example:
element.onclick = function(e) {
var aBetterEventObject = jQuery.Event(e);
// Now you can do what you want: (Cross-browser)
aBetterEventObject.preventDefault()
aBetterEventObject.isDefaultPrevented()
aBetterEventObject.stopPropagation()
aBetterEventObject.isPropagationStopped()
aBetterEventObject.stopImmediatePropagation()
aBetterEventObject.isImmediatePropagationStopped()
}
EDIT: Reading through your question again, I don't think propagation is the problem - you seem to want to cancel an event handler from running within an event handler - I'm not sure this is possible. You could just unbind all handlers (jQuery(elem).unbind('click')) but I don't think that's what you're after...
try to add the following line in the jQuery event handler:
return false;
Following on from JimmyP's answer. I've tried this
$('#x').click( function(e){
alert('hello');
});
document.getElementById('x').onclick = function(){
$('#x').unbind('click');
alert("goodbye");
}
The jQuery event runs once in this example. I don't think you can rely on the order of handlers being invoked however you define them, so I guess you'll have to accept that the jQuery event might fire once. Adding the onclick first does prevent the jQuery event from firing at all but, as I said, I don't think that's reliable.
Jquery has a method for namespacing events. http://docs.jquery.com/Namespaced_Events
You can add, trigger and remove separate functions bound to the same event via namespaces:
$("a").bind("click.custom1",function(){ ... });
$("a").bind("click.custom2",function(){ ... });
$("a").trigger("click.custom2");
$("a").unbind("click.custom2");
As long as you unbind the namespaced event your normal onclick should be unaffected. You may have to bind two separate namespaces to the click event as above if that doesn't work.

Categories

Resources