Stop animation using slideToggle - javascript

I have a button <button class="foo">Foo</button> with an event handler attached to it that expands or collapses a block using .slideToggle()
$('.foo').on('click', function () {
const fooBlock = $(this).next();
fooBlock.slideToggle(() => {
fooBlock.toggleClass('hidden');
});
If a user clicks the button when an animation is in transition then the click is queued. How do I stop the animation if the user clicks the button while the animation is already executing?

A much better solution is to just use stop(true) to clear the queue on successive clicks. This means the UI is still responsive to user input during the animation and also prevents the animations building up. Try this:
$('.foo').on('click', function() {
const fooBlock = $(this).next();
fooBlock.stop(true).slideToggle(() => {
fooBlock.toggleClass('hidden');
});
});

Related

JQuery - mousedown,mouseup and click on same element

I have a carousel and I need to make him work as Instagram carousel does.
On click change slide, but on mousedown just stop animation. My JQuery :
$(".fancy-carousel").on('mousedown',function (e) {
...stop animation
});
$(".fancy-carousel").on('mouseup',function (e) {
..continue animation
});
$(".fancy-carousel").on('click',function (e) {
..change slide
});
But i don´t know how can i let script know about difference between "click" and "mousedown". When i click on element and hold for a time, it stop animation but after "mouseup" it trigger "click" event too. Is there any way how to split this events? Or should i do it with some calculating of mouse hold time?
A “click” is just a full cycle of a “mousedown” and a “mouseup”. You can’t have one without the other.
For your code to know the difference, you’ll need a variable that tracks your intentions.
Create a variable to track your intention - default it to “click”.
var intention = "click";
In your mousedown function, pause the animation and start a timer. We will use this timer to detect how long the mouse is down for (I.e, if it’s for over a second, it’s not a click and you just want to trigger mouseup)
var detectIntention = setTimeout(function(){
intention = "mouseup";
})
In your mouse up function, cancel this timeout. If mouse up is called after just a few MS, then you want to do a click.
clearTimeout(detectIntention);
if (intention === "mouseup") {
// do mouseup stuff
}
// reset intention
intention = click;
Check in your click function that you wanted to do a click;
if (intention === "click") {
// do click stuff
}

jquery hide element when no interaction occurs

I have an element pop up in the screen on page load and it hides after 5 seconds. I'm trying to create logic where it'll hide if the user doesn't interact with the pop up, and if user does interact, it'll keep it shown, and if user leaves the element, the timer starts again to hide.
<div id="popup">
Some popup
<input type="email" placeholder="enter email" />
</div>
<div id="popup-button" style="display:none;">
button to open the popup
</div>
// on load, 5 seconds starts
var goTimeout = setTimeout(function(){
$('#popup').css("display","none");
$('#popup-button').css("display","block");
}, 5000);
goTimeout;
// when mouse enter's popup element and/or user types in input
// should turn off the setTimeout
$(document).on("touchstart click mouseenter keyup", "#popup", function(e){
e.stopPropagation();
e.preventDefault();
console.log(e);
clearTimeout(goTimeout);
});
// when user mouse leave's the popup the timer starts again, but
// if user is still focused within input field, don't start until
// user clicks outside of the element
$(document).on("mouseleave", "#popup", function(e){
e.stopPropagation();
e.preventDefault();
console.log(e);
clearTimeout(goTimeout);
goTimeout;
});
Was wondering if someone can help me with the logic, not getting it to work the way I like to
goTimer isn't a function but you're trying to call it like it is one at the end of your mouseleave section. Make a function that creates / starts the timer and you'll be good to go. Like this:
var goTimeout;
function myTimer() {
goTimeout = setTimeout(function() {
$('#popup').css("display", "none");
$('#popup-button').css("display", "block");
}, 5000);
}
myTimer();
Then just change the last line of your mouseleave section to be:
myTimer(); instead of goTimeout;
Here's a JSFiddle to check out.
You can use DOM elements like onmouseover, onmousedown, etc.
Also, the timeout declared at the end seems to be the error, it's more of a variable or count, than a function.
You can have something like,
Gotimeout=5;
clearTimeout(goTimeout);

Prevent clicking a link if scroll on mobile

I have long vertical list of links that user can scroll through, and I need to prevent triggering a click event (touch) on this links if user scrolls.
In current scenario, when user start scrolling by tapping over the link, it also triggers a click on link. Which is obviously bad. So, is there any way to prevent such a behavior?
Working fiddle
We could use a flag in this case to prevent click event just during the scroll and enable it after the scroll stop.
To listen on scroll stop you could use jQuery’s data method that gives us the ability to associate arbitrary data with DOM nodes and using setTimeout() function that will check every 250ms if the user still trigger the scroll, and if not it will change the flag :
var disable_click_flag = false;
$(window).scroll(function() {
disable_click_flag = true;
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
disable_click_flag = false;
}, 250));
});
$("body").on("click", "a", function(e) {
if( disable_click_flag ){
e.preventDefault();
}
});
Hope this helps.

Fire event when user stops to click

I'm able to detect a click on a button using jQuery
$('#myButton').click(function(){
// do something
});
but, when the user clicks many times on the button, it fires unnecessary intermediaries events.
I would like to fire the event only on the last click on the button.
Something like:
$('#myButton').lastClickOnASequenceOfClicks(function(){
// ignore the multiple clicks followed
// do something only on the last click of a sequence of clicks
});
With that, if the user clicks 10 times (with a little interval of time), it should fires an event only on the tenth click.
Each click resets the timer.
var timer;
$("#myButton").click(function () {
var timeToWait = 1000;
clearTimeout(timer);
timer = setTimeout(function () {
// do something only on the last click
}, timeToWait);
}
Update
Another way to solve this problem of handling 'multiple click events' generated by the user is to do what was mentioned in the OP comments section. do something on the first click THEN disable the button so the user cannot click it anymore (maybe also set a time for the button to become enabled again)
var timer, timeToWait = 5000, selector ="#myButton";
$(selector).click(function (e) {
$(this).attr("disabled", "disabled");
// do something
// Then wait a certain amount of time then remove the disabled attr on your button
timer = setTimeout(function () {
$(selector).removeAttr("disabled");
}, timeToWait);
})

Display DIV only if user has been Idle for X amount of time

I would like to display a helpful DIV that basically shows the user how to accomplish something on a particular page, but only if the user has been idle for a period of time, say, 30seconds.
What I mean by "Idle" is:
Not clicking any links
Not right clicking anywhere
Exceptions:
I would like to exclude the following conditions from the Is User Idle rule:
User has scrolled up or down/left or right
User has pressed mouse button on an empty area on the site/ or on an element which has no source/link for example, an image with no hyperlink.
and, Pressing keyboard buttons
Can this be done? Or can we only detect when a particullar event occurs?
Any thoughts/suggestions/resources will be greatly appreciated.
Thank you
fairly basic...
var trigger = 30000
$.(function(){
setInterval('displayInf()',trigger );
$('body').bind('click dblclick keypress mousemove scroll', function(){
clearDisplayInf();
});
});
function displayInf()
{
$('body').append('<div>Your notification div</div>');
}
function clearDisplayInf()
{
trigger = clearInterval(trigger);
trigger = setInterval('displayInf()', 30000 );
}
that should do the trick - you could add some script to make the div removable and start the timer again once its removed but that just polishing up really..
Event in DOM would bubble from leaf to root, thus add a event listener on document would make sense.
But since we are possibiliy stop bubbling for click event in certain element, register click event on document may not work perfectly, in that case, register mousedown and mouseup event would help:
var timer; // create a timer at first
// restart timer on click
function startIdle() {
timer = setTimeout(function() { /* show div */ }, time);
}
if (document.addEventListener) {
document.addEventListener('mouseup', startIdle, false);
}
else {
document.attachEvent('onmouseup', startIdle);
}
// start the first timer
startIdle();

Categories

Resources