Prevent Multiple Clicks in JQuery - javascript

I am creating a dynamic quiz and I need to prevent multiple clicks on my 'next' button. In the click function I tried to an if condition to prevent multiple clicks. Not sure why it doesn't work. Would greatly appreciate some help.
var nextButton= $('<button/>', {
text: 'Next',
id: 'nextButton',
click: function (event) {
event.preventDefault();
if($("#container").filter(':animated').length>0) {
return false;
}
/* rest of code*/
}
});
Here is the code as it appears my JSFiddle of my application
Bonus Question: I was told event.preventDefault() is good practice. Is this true? If so, why?
Update: The JSFiddle line # where the code above is line 81 in case you want to mess around with the code without digging through it all.

var nextButton= $('<button/>', {
text: 'Next',
id: 'nextButton',
click: function (event) {
event.preventDefault();
if($("#insideContainer").filter(':animated').length>0) {
return false;
}
/* rest of code*/
}
});
I found out why. You're checking against the wrong element. It should be #insideContainer
Demo

Try like this
$("#id or .class").one("click",function(){
// your activity
});
Description:
The one() method attaches one or more event handlers for the selected elements, and specifies a function to run when the event occurs.
When using the one() method, the event handler function is only run ONCE for each element.

One way to do this to use timeStamp property of event like this to gap some time between multiple clicks:
var a = $("a"),
stopClick = 0;
a.on("click", function(e) {
if(e.timeStamp - stopClick > 300) { // give 300ms gap between clicks
// logic here
stopClick = e.timeStamp; // new timestamp given
}
});

Try to use event.stopImmediatePropagation() to prevent multiple clicks.
Desc: Keeps the rest of the handlers from being executed and prevents the event from bubbling up the DOM tree.

Related

jQuery calling on() on dynamically generated it after calling click()

I am trying to develop some code to allow the user show/hide a block level element by clicking a button.
The HTML structure is like below
<div class="chat_container"><a class="crm" href="https://google.com" target="_blank">Chat?</a><button id="close_chat"><</button></div>
I have written a click() function for #close_chat which amongst other things changes the ID of the button to #open_chat. I then use the on() method on #open_chat to modify some classes and ids on various elements. In isolation both these methods work, however when combined they don't work. I have noticed that when I click #close_chat even though the ID changes to #open_chat the original event is still attached to the button. After doing some search I suspected the issue might have been related to events bubbling up, but now I am not so sure, still I added event.stopPopagation() to my click function and I can see it appears to be called correctly. I have also tried using the one() method, this appeared to get closer to the behavior I was expecting at the DOM level but still didn't working
My expected behavior is the click() function is called when the user clicks #close_chat, the event is then unbound allowing the .on() event to be called on #open_chat. Id than of course have to reset the original functionality. My code looks like this
$(document).ready(function () {
var close = "<button id='close_chat'><</div>";
var container = $("<div />");
container.addClass("chat_container");
var crmChat = $("<a />");
crmChat.addClass("crm");
crmChat.attr("href", "https://google.com");
crmChat.attr("target", "_blank");
crmChat.text("Chat?");
console.log(crmChat);
console.log(container);
$(container).insertAfter("#heading");
$(container).prepend(crmChat);
$(close).insertAfter(crmChat);
$("#close_chat").click(function (event) {
$("#close_chat").removeAttr("id").attr("id", "open_chat");
event.stopPropagation();
alert(event.isPropagationStopped());
//return false;
});
$(".chat_container").on("#open_chat", "button", function () {
//$(".crm_chat_container").addClass("animate-open").removeClass("animate-close");
$("#open_chat").html(">").removeAttr("id").attr("id", "reopen");
//event.stopPropagation();
});
});
any help is greatly appreciated
Sam
edit, I have now updated my code to look like so
//onclick function for our close button
$("#close_chat").click(function (event) {
attachClosedChatListner();
});
function attachOpendChatListener() {
$(".chat_container").on("click","#open_chat", function () {
$("#open_chat").removeAttr("id").attr("id", "close_chat");
$("#close_chat").html("<")
$(".crm_chat_container").removeClass("animate-close").addClass("animate-open");
});
//attachClosedChatListner();
}
function attachClosedChatListner() {
$("#close_chat").off('click');
$("#close_chat").removeAttr("id").attr("id", "open_chat");
$("#open_chat").html(">")
$(".chat_container").removeClass("animate-open").addClass("animate-close");
//attachOpendChatListener();
}
What about re-attaching the event?
$("#close_chat").click(function (event) {
$("#close_chat").removeAttr("id").attr("id", "open_chat");
attachOpenChatListener();
event.stopPropagation();
alert(event.isPropagationStopped());
//return false;
});
function attachOpenChatListener() {
$("#close_chat").off('click');
$(".chat_container").on("#open_chat", "button", function () {
//$(".crm_chat_container").addClass("animate-open").removeClass("animate-close");
$("#open_chat").html(">").removeAttr("id").attr("id", "reopen");
//event.stopPropagation();
});
}
I managed to work this out, the click function was causing the problem
//onclick function for our close button
$("#close_chat").click(function (event) {
attachClosedChatListner();
});
I've replaced it with .on and it works now
$(".crm_chat_container").on("click", "#close_chat", function (event) {
$("#close_chat").off('click');
$("#close_chat").removeAttr("id").attr("id", "open_chat");
$("#open_chat").html(">");
$(".crm_chat_container").removeClass("primo-animate-open").addClass("animate- close");
attachCloseChatListener();
event.stopImmediatePropagation();
});
function attachCloseChatListener() {
$(".crm_chat_container").on("click", "#open_chat", function (event) {
$("#open_chat").off('click');
$(".crm_chat_container").removeClass("primo-animate-close").addClass("primo-animate-open");
$("#open_chat").removeAttr("id").attr("id", "close_chat");
$("#close_chat").html("<");
event.stopImmediatePropagation();
});
}
on thing is my click events appears to be firing multiple times, that is after clicking my buttons a few times I see several click events in dev tools.
Anyway, thanks for putting me on the right path

Mouseover(show content) javascript

I'm new to JavaScript, I wonder, how can I make this:
I have menu item, then you click on it, info box pops up, there's X in corner, you close it and that's it. But my goal is not only on click show it, but even then you hover it. Here's script, if you need CSS let me know.
$('#help').appendTo('.navbar-container .level1');
$('#help a').click(function(e) {
e.preventDefault();
if($('#help').hasClass('active')) {
$('#help').removeClass('active');
} else {
$('#help').addClass('active');
}
$('#help-block').toggle();
});
$('#help-block .help-close').click(function(e) {
e.preventDefault();
$('#help-block').css('display','none');
$('#help').removeClass('active');
});
Thanks, people! Happy new year.
Multiple events can be bound to one .on() method, e.g:
$('#help a').on('click hover', function(e) {
// continue
});
Description: Attach an event handler function for one or more events to the selected elements.
Ref: .on() | jQuery API Documentation
Consider using this method instead.
Use .on() and mouseover like this:
$('#help').appendTo('.navbar-container .level1');
$('#help a').on("click mouseover",function(e) {
e.preventDefault();
if($('#help').hasClass('active')) {
$('#help').removeClass('active');
} else {
$('#help').addClass('active');
}
$('#help-block').toggle();
});
$('#help-block .help-close').on("click mouseover",function(e) {
e.preventDefault();
$('#help-block').css('display','none');
$('#help').removeClass('active');
});

Why does my removeEventListener not work?

I am working on building a simple script where a user click's either a blue button or a red button. When the blue button's are clicked the one the user clicks on should fade out, which works fine. However if the user clicks the red button then the fade out on the blue will stop. Like I said the blue buttons work but the red one doesn't.
Looking at various questions and answers on here and other sites I believe that the code I have is correct and it seems that the reason it won't work is because they don't match, i.e. I am not actually removing the add event.
The code I have is below and any help would be appreciated, I am using Adobe Animate to code in:
instance = this;
instance.stop();
//Buttons array
var lowerQuestions = [instance.BTN1, instance.BTN2, instance.BTN4];
//Add an event listener to each button in the array
addEventListeners();
function addEventListeners(){
lowerQuestions.forEach(function(element) {
element.addEventListener("click", function(){
console.log('add listener');
addButtonValue(element);
},false);
});
}
//Remove event listeners when BTN3 is clicked
instance.BTN3.addEventListener("click", removeEventListeners)
function removeEventListeners(){
console.log('prevent');
lowerQuestions.forEach(function(element) {
element.removeEventListener("click", function(){
console.log('remove listener');
addButtonValue(element);
//console.log('hit me here');
},false);
});
}
//Event listener function
function addButtonValue(element){
instance.addEventListener("tick", fadeOut);
element.alpha = 1;
function fadeOut(){
element.alpha -= 0.15;
if(element.alpha <= 0){
instance.removeEventListener("tick", fadeOut);}
}
}
For remove event listener of the element you have two choice. 1- make a copy of element and replace with this one. 2- put name for listener function and pass it to remove event listener.
In your code i suggest first solution. This code can help you, for every single element that you want remove listener should run this code :
function removeEventListeners(){
console.log('prevent');
lowerQuestions.forEach(function(element) {
var cln = element.cloneNode(true);
element.parentNode.appendChild(cln);
element.parentNode.removeChild(element);
});
}
Are anonymous functions able to handle removeEventListener? discusses why anonymous function expressions are not great for event listeners that need to be removed - function expressions produce a different function object each time they are executed, so the remove function never matches the added function.
A simple solution in this case is to create the listener using a standard named function declaration:
function buttonClicked(){
addButtonValue( this);
}
addEventListeners();
function addEventListeners(){
lowerQuestions.forEach(function(element) {
element.addEventListener("click", buttonClicked, false);
});
}
which make the listeners removable by name:
//...
lowerQuestions.forEach(function(element) {
element.removeEventListener("click", buttonClicked, false);
});
//...

Prevent certain functionality based on element clicked

I've got a button .btn-1 that when clicked also triggers click on .btn-2 I can't think of a way to do the following: when .btn-2 is clicked also trigger click on .btn-1 however in this case dismiss its functionality to trigger click on '.btn-2' to prevent infinite loop. Is there a way to achieve this?
You can pass additional data to your handler using .trigger() method:
$('.btn-2').on('click', function(event, skip) {
// if the skip parameter is a truthy value
// don't trigger the event
if ( !skip ) {
$('.btn-1').trigger('click', [true]);
}
});
$('.btn-2').trigger('click', [true]);
you can use a boolean that switches:
var done=true;
$('.btn-1').click(function(){
$('log').html($('log').html()+'bt1 pressed<br>')
if(done){
done=false;
$('.btn-2').click()
}
done=true;
})
http://jsfiddle.net/2o3k5wet/
A more elegant way to do this:
$('.btn-1, .btn-2').on('click', function() {
// do common stuff
if ($(this).is('.btn-1')) {
// do stuff only for 1
}
// do common stuff
});

codeschool jQuery Return Flight 5.10 on click handler failing

I am running into an odd issue with codeschools jquery course where my on click handler is not working. The question we are trying to solve in 5.10 is:
For starters create an event handler using on, that targets the
.see-photos link within each .tour. When this is clicked, run a
function that will add a class of is-showing-photofy to the tour.
You'll probably want to save a reference to this outside of your event
handler, and use that in the click event handler.
My current code attempt is:
$.fn.photofy = function() {
this.each(function() {
var tour = $(this)
tour.on('click.see-photos', 'button', function() {
$(this).addClass('is-showing-photofy');
});
});
}
$(document).ready(function() {
$('.tour').photofy();
});
and the error message I am getting is:
Your `on` `click` handler should watch for clicks on the `.see-photos` element within the current tour
Can anyone point me in the right direction?
I was missing the following:
prevent default
var tour = $(This)
Final Code:
$.fn.photofy = function() {
this.each(function() {
var tour = $(this);
tour.on('click.photofy', '.see-photos', function(event) {
event.preventDefault();
tour.addClass('is-showing-photofy');
});
});
}
$(document).ready(function() {
$('.tour').photofy();
});

Categories