I have this sample code here
http://jsfiddle.net/DBBUL/10/
$(document).ready(function ($) {
$('.creategene').click(function () {
$('#confirmCreateModal').modal();
$('#confirmCreateYes').click(function () {
$('#confirmCreateModal').modal('hide');
var test = "123";
alert(test);
console.log(test);
});
});
});
If you click the create button 3 times and each time you click yes on the confirmation, the alert is fired multiple times for each click instead of just one time.
If you click the create button 3 times and each time you click no and on the 4th time you click yes the alert is fired for each of the previous clicks instead of just one time.
this behavior seems weird to me as i would expect the alert to be fired once per click. Do I have to use .unbind() or is there a better solution?
Could someone please tell me why this is happening and how to fix it?
Thanks
Because you are binding it multiple times. Click event inside a click event means every time you click, a new click event is being bound on top of the previously bound events. Do not bind click events inside of click events unless the click event creates the element. There's also no need to re-initialize the modal over and over.
$(document).ready(function ($) {
$('#confirmCreateModal').modal({show: false});
$('#confirmCreateYes').click(function () {
$('#confirmCreateModal').modal('hide');
var test = "123";
alert(test);
console.log(test);
});
$('.creategene').click(function () {
$('#confirmCreateModal').modal('show');
});
});
Demo
change the code like this
$(document).ready(function ($) {
$('.creategene').click(function () {
$('#confirmCreateModal').modal();
});
$('#confirmCreateYes').click(function () {
$('#confirmCreateModal').modal('hide');
var test = "123";
alert(test);
console.log(test);
});
});
fiddle
You dont have to bind $('#confirmCreateYes').click in each button click.
You can try this also -
$("#confirmCreateYes").unbind().click(function() {
//Stuff
});
Add this to your code:
$( "#confirmCreateYes").unbind( "click" );
Like this:
$(document).ready(function ($) {
$('.creategene').click(function () {
$('#confirmCreateModal').modal();
$('#confirmCreateYes').click(function () {
$('#confirmCreateModal').modal('hide');
var test = "123";
alert(test);
console.log(test);
$( "#confirmCreateYes").unbind( "click" );
});
});
});
It will unbind the event, so that it isn't bound on top of the previous event. This allows the event only to fire within the original click event.
This is not a good method. It will unbind all click events attached to the element. I will leave it here for learning purposes.
As of now its the below code worked for me,
$("#parentID").off("click", ".button").on("click", ".button", function(e){
e.preventDefault(); // stop probagation if its button or a href
// your code here
});
Related
I have a series of messages on my page that are triggered by a keydown event once people start typing in a textarea. However, I can't figure out how to trigger it only once. Since people are typing longer responses, the function runs every time a key is pressed :/
$(function() {
$(document).on('keydown', function() {
$('.three').delay(1000).fadeOut(1500);
$('.four').delay(2500).fadeIn(1500).delay(2000).fadeOut(1500);
$('.five').delay(7500).fadeIn(1500).delay(2000).fadeOut(1500);
$('.6').delay(12500).fadeIn(1500).delay(2000).fadeOut(1500);
$('.7').delay(17500).fadeIn(1500);
});
});
Instead of "on" use "one". This handles the event only once.
$(function() {
$(document).one('keydown', function() {
$('.three').delay(1000).fadeOut(1500);
$('.four').delay(2500).fadeIn(1500).delay(2000).fadeOut(1500);
$('.five').delay(7500).fadeIn(1500).delay(2000).fadeOut(1500);
$('.6').delay(12500).fadeIn(1500).delay(2000).fadeOut(1500);
$('.7').delay(17500).fadeIn(1500);
});
});
Here's the reference: http://api.jquery.com/one/
I have tested many and many solution but any solve my problem.
I have a simple html table. Each row have a edit button.
Jquery is firing many time when I click on the edit button.
Example : I click the first time on a edit button, all work fine. After that, I click on a second edit button and then jquery is firing 2 time, ...
$('.edit').one('click', function(e)
{
e.preventDefault();
e.stopPropagation();
$(this).unbind('click');
var tr = $(this).closest('tr');
var saveUrl = $(this).attr('href');
$('.form-edit').submit(function(e)
{
e.preventDefault();
e.stopPropagation();
console.log($('.form-edit').serialize());
});
});
stopPropagation, return false, unbind, ... change nothing.
What is the problem with my code ?
Simply resolved with this code : unbind then bind
$('.form-edit').unbind('submit').bind('submit', function(event)
{
...
}
I have the following HTML-table:
<table>
<tr>
<td>
Row 1
</td>
<td>
<!-- Hidden JSF-button -->
<button class="hide" />
</td>
</tr>
</table>
When I click on a tr, I trigger a click on the hidden button with JS:
$('table tr').on('click', function(e) {
var $button = $(this).find('button');
console.log('trigger click on', $button);
$button.trigger('click');
});
The click event propagates up, and will cause a never ending loop (can be seen here: http://codepen.io/anon/pen/kDxHy)
After some searching on Stack Overflow, it is clear that the solution is to call event.stopPropagation,
like this (can be seen here: http://codepen.io/anon/pen/BnlfA):
$('table tr').on('click', function(e) {
var $button = $(this).find('button');
// Prevent the event from bubbling up the DOM tree.
$button
.off('click')
.on('click', function(e) {
console.log('click');
e.stopPropagation();
return true;
});
console.log('trigger click on', $button);
$button.trigger('click');
});
The solution above works. But it feels like a hack, and I don't like it.
Do I have to register a click handler on the on the $button just to call event.stopPropagation? Are there any better way(s) of preventing the click event from bubbling?
A better overall solution would be not to trigger the click event at all but simply have a seperate function that you can call and that encapsulates the event handler logic.
function doSomething(someArg) {
//do something
}
$('button').click(function () {
doSomething(/*pass whatever you want*/);
});
$('table tr').on('click', function () {
doSomething(/*pass whatever you want*/);
});
Please note that doSomething doesn't have an event handler signature such as (e). That's generally a good practice to pass just what's needed to the function to do it's own work, not the whole event object. That will simplify the implementation of doSomething and decouple it completely from the event object.
EDIT:
Sorry, but I need to manually trigger the button click when the user
clicks on a tr. Please see my comment to #magyar1984 question.
In this case you probably found the best solution already, which is to attach an event listener on the button and call stopPropagation. You could also look into getting all click event handlers by using the events data on the element, but beware that you would then be relying on jQuery internals so the code could break in future releases.
Have a look at this question to know how to retrieve the event handlers.
I was able to get it to only register the button click once by updating your codepen to the following:
var handleClick = function(e) {
var $button = $(this).find('button');
console.log('trigger click on', $button);
$button.trigger('click');
};
$('button.hide').on('click',function(e){
e.stopPropagation();
});
$(function() {
$('table tr')
.on('click', handleClick);
});
But the general idea is to declare an onClick event on the button and stop the propagation there.
Modifying buttons behaviour, expecially in frameworks, can cause some unexpected issues. You could add a flag to the row and use it to check if the button should be clicked. But you have to know how many click are automatically generated and should be omitted.
var handleClick = function(e) {
var $button = $(this).find('button');
console.log('triggerring click on...', $button);
if (this.clicked !== true) {
console.log('and clicked!')
this.clicked = true;
$button.trigger('click');
} else
this.clicked = false;
};
Here's the code: http://codepen.io/anon/pen/dJroL
Right, I'm getting quite aggitated with this. I'm probably doing something wrong, but here's what I'm doing:
$(document).ready(function () {
$('#somebutton').click(function () {
openPage1();
});
$('#someotherbutton').click(function () {
openPage2();
});
});
var openPage1 = function () {
$('#iframe').attr('src', 'someurl');
$('#iframe').load(function () {
$('#button').click();
});
};
var openPage2 = function () {
$('#iframe').attr('src', 'anotherurl');
$('#iframe').load(function () {
$('#anotherbutton').click();
});
}
Whenever I click somebutton everything goes as expected. However when I click someotherbutton. The .load() from openPage1() is called first and I can't find a way to stop that. The .load() from openPage1() has a button with the same name, however on openPage2() I need to modify the contents before clicking the buttons.
I need to use .load() because I can't click the buttons before the document is ready.
Basically what I need is two seperate .load() instances on the same iframe, that don't fire off on each other.
Besides that, maybe my understanding of jQuery/JS is wrong, but shouldn't the .load() events only be listening after clicking the corresponding button?
Can someone help me out, this has been keeping me busy all afternoon.
Try using on, and once loaded, unbind
$("#iframe").on("load", function(){
$(this).off("load");
$('#button').click();
});
That way you remove the handler you put up before the second button is clicked?
By writing : $('#iframe').load(function (){ $('#button').click(); });, you are adding a listener on the load event, which will stay and be re-executed on each subsequent reload of the iframe.
Here is a jsfiddle to demonstrate this : click on the "reload" button, and see how many times the "loaded" message appears in your console.
in your case, if you click on #somebutton, then on #someotherbutton, after the second click, you will have two handlers bound on the load event, and both will be triggered.
If you click 5 times on #somebutton, you should end up calling 5 times $('#button').click().
If you want to execute it once, you can follow Fred's suggestion, or use jQuery .one() binder :
$('#iframe').one('load', function(){ $('#button').click() });
Here is the updated jsfiddle : 'loaded' should be displayed only once per click.
Maybe try and replace the lines in both functions like this:
$('#iframe').load(function() {
$('#anotherbutton').click();
};
$('#iframe').attr('src', 'anotherurl');
Otherwise it might be firing the event before the new event-handler has been set.
This isn't really an answer to your problem Now it is an answer, but I think utilizing functions as they were intended could be beneficial here, i.e.:
//Utilize a single function that takes arguments
var openPage = function (frame, src, eventEl) {
frame.attr('src', src); // If you pass frame as a jQuery object, you don't
frame.on("load", function(){ // need to do it again
$(this).off("load");
evEl.click(); //Same for your buttons
});
}
//Simplify other code
$(document).ready(function () {
$('#somebutton').click(function () {
openPage($("#iframe"),somehref,$("#buttonelement"));
});
$('#someotherbutton').click(function () {
openPage($("#iframe"),anotherhref,$("#someotherbuttonelement"));
});
});
I have an element, a div, for example. And attach an event 'click' to it. In jQuery, it would be:
$('#myDiv').click(function(){
$(".class1").show();
})
Now, I would like to assign a new function "myDiv #", replacing the old. I am doing so:
$('#myDiv').click(function(){
$(".class23").hide();
})
But when I run the 'click' on the div, the function I assigns the beginning of this doubt is performed.
Question: How to remove the function that will run with the click event attributed to an element? (No recreate the element with the new click event...)
You want .unbind.
You can either remove all previous bound functions:
$('#myDiv').unbind('click');
Or if you only want to unbind one specific function:
var show = function() {
$(".class1").show();
};
$('#myDiv').click(show);
and then:
$('#myDiv').unbind('click', show); // unbind first function
$('#myDiv').click(function() { // bind second function
$(".class23").hide();
});
Note that .click(func) is just a shortcut to .bind('click', func).
If you know you'll only want to handle one click on an element, you can use one() which automatically unbinds after a single click:
$("#myDiv").one("click", function() {
$(".class1").show();
$("#myDiv").one("click", function(){
$(".class23").hide();
});
});
Use the JQuery unbind function to remove all click events
$('#myDiv').unbind('click');
Add a counter on the first click event.
var counter = 0;
$('#myDiv').click(function(){
if(counter>1){
$(".class23").hide();
}
else
$(".class1").show();
counter++;
})
just an example..