jquery stop delegated event from being called twice - javascript

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();

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");
});

js stop click function subsequent execution after call back in ajax of itself

On the first click myClick() has been called again in itself of myLoad() then at the second click, this myClick() will execute two times
=> The following causes two subsequent execution of
click event of #myBtn by one click
How to avoid or stop this? Please anybody suggest me new logical method or which way to stop this.
$(function() {
myLoad()
})
function myClick() {
$("#myBtn").click(function() {
myLoad(); //load new every click
});
}
function myLoad() {
$("#myCnt").load('ajax.php', {
"data": "some"
}, function() {
myClick() //to live the click event works after ajax load
})
}
Problem with your implementation is that in each call to myClick() an new event handler is attached to button.
You can use .off() to remove existing event handler attached using .on().
function myClick(){
$("#myBtn").off('click').on('click', function(){
myLoad();//load new every click
});
}
A better approach would be to use .on() method with Event Delegation approach, when generating elements dynamically.
General Syntax
$(document).on('event','selector',callback_function)
In place of document you should use closest static container.
The delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, we can use delegated events to bind the click event to dynamically created elements and also to avoid the need to frequently attach and remove event handlers.
A good read Direct and delegated events
Modify you code as
$(function() {
myLoad();
$(document).on("click", "#myBtn", function() {
myLoad(); //load new every click
});
})
function myLoad() {
$("#myCnt").load('ajax.php', { "data": "some"}, function() {
//No need to call my click
})
}
Issues is in the flow of your code
First time when you call myClick() it binds the click event with #myBtn,
On second time it binds that event again , so it will be called twice , remove that event binding from there,
Or else $("#myBtn").click will be bind each time you call the myClick function.
As solution please try this code :
$(function(){
myLoad()
})
$("body").on( "click" , "#myBtn" , function(){
myLoad();//load new every click
});
function myLoad(){
$("#myCnt").load('ajax.php', {"data":"some"}, function(){
$("#myBtn").trigger("click");
})
}

Is it possible to execute an inline click event function without executing a click event?

Explaining by example:
$(".myCheckboxes").click(function () {
...
});
Inside the click event function I have code that does various things depending on what checkboxes are checked.
I however need to run this code to initialize it first, kindof like this:
$(".myCheckboxes").click(function () {
...
}).click();
It runs the code and it gets initialized, but it also clicks on all my checkboxes making them all invert their value.
Is it possible to execute the inline click event function wihtout executing a click event?
I would very much like to keep the function inline to keep the flow of the code. Also, it's not big enough to have the function outside of the event, but it's not so small as I would like to write the code twice.
triggerHandler triggers only the handler:
$(".myCheckboxes").click(function () {
...
}).each(function(i, checkbox) {
$(checkbox).triggerHandler('click');
}
Note that you need to iterate the checkboxes if you wish to trigger the handler for all of them instead of just the first one:
while .trigger() will operate on all elements matched by the jQuery
object, .triggerHandler() only affects the first matched element.
Use a named function as the handler, bind it and execute it:
$(".myCheckboxes").click(clickHandler);
clickHandler();
You may consider to call the function triggerHandler who seems to do what you need.
$(".myCheckboxes").click(function () {
...
}).triggerHandler('click');
NB: I haven't tested this solution.

Create event function gets executed in creation

I've tried searching for an explanation to my issue below but it's possible the keywords I used are to ambiguous.. so I turn to you.
I'm trying to implement a click outside menu to close based on this code here which is:
$('#menuscontainer').click(function(event) {
//your code that shows the menus fully
//now set up an event listener so that clicking anywhere outside will close the menu
$('html').click(function(event) {
//check up the tree of the click target to check whether user has clicked outside of menu
if ($(event.target).parents('#menuscontainer').length==0) {
// your code to hide menu
//this event listener has done its job so we can unbind it.
$(this).unbind(event);
}
})
});
However it seems the function in $('html').click... gets executed when clicking on the #menucontainer so it just open and immediately closes.
I've simplified it to:
$('.trig').click(function () {
$('.menu').show();
$('body').click( function () {
alert('boo');
});
});
Here's the JSFiddle link.
As you can see alert gets executed when .trig is clicked on. So instead of just creating the even listener, it seems to already be listening.
Can someone please explain this to me? Thanks.
Events bubble to parents also.
You can prevent this by using event.stopPropagation()
$('.trig').click(function (e) {
e.stopPropagation();
$('.menu').show();
$('body').click( function () {
alert('boo');
});
});
Since you are adding a click handler to the body before the event is over it is also being triggered on the body
Reference: https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation
DEMO

how to bind again the click event for the button

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.

Categories

Resources