I have a slider script which use setInterval to run next slider function for a period of time, this function also called by another event listener, the problem is the function can run at nearest period, so the transition is bad. I want to make setInterval pause for awhile when I run the function from event listener.
$(document).ready(function () {
setInterval(function () {
next();
}, 5000);
function prev() {
//slide in to left
};
function next() {
//slide in to right
};
$('#prev').click(function (e) {
pause = 1;
prev();
setTimeout(function(){
pause = 0;
}, 3000);
});
$('#next').click(function (e) {
pause = 1;
next();
setTimeout(function(){
pause = 0;
}, 3000);
});
});
Related
I want to click on a point and delete it, but when i press my mouse button down for 3 seconds, i want to do something else with this point. My problem is, that the code doesnt clear the timer, it just deletes the point after 3 seconds, no matter how long i clicked it on the point.
Im working with setTimeout and clearTimeout.
function click(event,d){
timer= setTimeout(function(){
/* do something */
},3000)
}
function clickRelease(timer){
clearTimeout(timer)
}
divMag1=d3.selectAll(".scatterlayer .trace .points path ")
divMag1.on("mousedown", click)
divMag1.on("mouseup",clickRelease)```
V3 - I think you're deleting the target before you can execute what you want.
Note that setTimout may take more than 3 seconds to execute.
Try:
function click(event) {
const currentTarget = event.currentTarget; // for some reason event.target is null in the timer handler, this fixes it 🤷
const timer = setTimeout(() => {
currentTarget.removeEventListener('mouseup', deleteTarget);
console.log('stuff');
// do stuff
}, 3000);
function deleteTarget() {
clearTimeout(timer);
console.log('deleted');
currentTarget.removeEventListener('mouseup', deleteTarget); // not required if you're actually deleting the target
// remove target
}
currentTarget.addEventListener('mouseup', deleteTarget);
}
document.querySelector('#but').addEventListener('mousedown', click)
<button id="but">Click</button>
V1:
let timer;
function click(event,d){
timer= setTimeout(function(){
/* do something */
},3000);
}
function clickRelease(){
clearTimeout(timer)
}
divMag1=d3.selectAll(".scatterlayer .trace .points path ")
divMag1.on("mousedown", click)
divMag1.on("mouseup",clickRelease)
You should first declare timer variable. Then to make your mouseup event works on you should wrap clickRelease to event funtion again or use it simply:
...
.addEventListener("mouseup", function() { clearTimeout(timer) })
Working example with button:
var timer
function click(event, d) {
timer = setTimeout(function () {
console.log('do something')
}, 1000)
}
function clickRelease(timer){
clearTimeout(timer)
}
var divMag1 = document.querySelector('#but')
divMag1.addEventListener("mousedown", click)
document.addEventListener("mouseup", function() { clickRelease(timer) })
<button id="but">Click</button>
If you want event to doing something repeatedly while button is down you need to use setInterval not setTimeout like this:
var timer
function click(event, d) {
timer = setInterval(function () {
console.log('do something')
}, 1000)
}
var divMag1 = document.querySelector('#but')
divMag1.addEventListener("mousedown", click)
document.addEventListener("mouseup", function() { clearInterval(timer) })
Note for clearing interval uses clearInterval not clearTimeout. Also the mouseup event handler attached on whole document in my solution not on button.
I've got a function within a window.resize event and it works well, apart from that it seems to only works once. If the user resizes the window again the function isn't executed. This is the code:
$(window).resize(function() {
var wait = setInterval(function () {
if (!$(currentBanner, loading).is(":animated")) {
clearInterval(wait);
loading.stop().fadeOut(300, function () {
if ($('#banner').css('display') == 'block'){
setTimeout(function() {
bannerInit();
}, 800);
startInterval();
if (initialLoad) {
initialLoad = false;
next.slideDown();
previous.slideDown();
}
}
});
}
}, 200);
}).resize();
Anybody know how I can make sure that the function is executed every time the window is resized?
I don't know what was your intention but if it was to have a delayed execution after the window resize you should change setInterval to setTimeout
setInterval is a infinite loop that runs until you tell it to stop and setTimeout is only executed once and it will wait x milliseconds to be executed.
Plus, you dont need to call 'resize()' event, it will be fired everytime the window size is changed by any reason (user resizing or maximizing, etc)
$(window).on("resize",function() {
var wait = setTimeout(function () {
if (!$(currentBanner, loading).is(":animated")) {
clearInterval(wait);
loading.stop().fadeOut(300, function () {
if ($('#banner').css('display') == 'block'){
setTimeout(function() {
bannerInit();
}, 800);
startInterval();
if (initialLoad) {
initialLoad = false;
next.slideDown();
previous.slideDown();
}
}
});
}
}, 200);
});
That's because you're calling .resize() at the end of the event definition.
Try changing to:
$(window).resize(function () {
//....
});
$(window).resize();
I have an image gallery that rotates through the rotator class divs on www.creat3dprinters.com that pauses on mouseenter and then fires again 1 second after mouseleave.
However, if a user moves the mouse in and out of the rotator class div quickly the function calls stack up and the visible changes until the 'stack' is completed.
I want the 1 second delay that has not been completed to be cancelled on the 2nd and subsequent mouseenter so that this does not happen.
I have tried using clearTimeout within the mouseenter function but it does not seem to work.
I know there is also the stop() function but that did not work either.
Any suggestions greatly appreciated.
jQuery(document).ready(function () {
var initList = setInterval('RotateIt()', 4000);
$('.rotator').mouseenter(function () {
clearInterval(initList);
}).mouseleave(function () {
timeout = setTimeout(function () {
RotateIt()
}, 1000);
initList = setInterval('RotateIt()', 4000);
})
});
function RotateIt() {
clearTimeout(timeout);
if ($('#rotator-visible').next('.rotator').length == 0) {
$('.rotator:first').attr('id', 'rotator-visible');
$('.rotator:last').removeAttr("id");
} else {
$('#rotator-visible').removeAttr("id").next('.rotator').attr("id", "rotator-visible");
}
}
If a user moves the mouse in and out of the rotator class div quickly the function calls stack up
Then clearTimeout it - and in exactly that place, not only in the delayed RotateIt. The simplest solution would be to call clearTimeout every time before setTimeout, so that you can be sure there is only one active timeout at once.
jQuery(document).ready(function($) {
var initList = setInterval(rotateIt, 4000),
delay = null;
$('.rotator').mouseenter(function(e) {
clearInterval(initList);
}).mouseleave(function(e) {
clearTimeout(delay);
delay = setTimeout(function () {
rotateIt();
initList = setInterval(rotateIt, 4000);
}, 1000);
})
});
function rotateIt() {
if ($('#rotator-visible').next('.rotator').length == 0) {
$('.rotator:first').attr('id', 'rotator-visible');
$('.rotator:last').removeAttr("id");
} else {
$('#rotator-visible').removeAttr("id").next('.rotator').attr("id", "rotator-visible");
}
}
I'm putting together some code to essentially replace the contents of a div when I mouseover a specific link. I then added the changer function to cycle through the content replacement automatically. I set flags for mouseover and mouseout and I can actually get the changer function to stop on mouseover but I can't quite figure out how to make it start up again on mouseout. Any advice is appreciated.
var pause=false;
$('.banner-nav a').mouseover(function () {
pause=true;
setFeature(this);
return false;
});
$('.banner-nav a').mouseout(function () {
pause=false;
});
changer(0, 5000);
function setFeature(f) {
var m = $(f).attr('rel');
$('.banner-nav a').not(f).removeClass('active');
$(f).addClass('active');
$('#featureContainer').html($(m).html());
}
function changer(index, interval) {
var buttons = $('.trigger'),
buttons_length = buttons.length;
var button = buttons.eq(index % buttons_length);
setFeature($(button));
setTimeout(function() {
if (!pause) {
changer(++index, interval);
}
}, interval)
}
The issue is that changer is responsible for its own delayed execution, but pausing it stops the scheduled execution. Another problem is that the next scheduled execution (if any) still happens after pausing.
Use setInterval instead of setTimeout. Instead of using a flag, clear the interval to pause and start it again to unpause.
(function() {
var index=0;
function changer() {
var buttons = $('.trigger'),
buttons_length = buttons.length;
var button = buttons.eq(index % buttons_length);
setFeature($(button));
++index;
}
var changerInterval,
period = 5000;
function startChanger() {
if (! changerInterval) {
changerInterval = setInterval(changer, interval);
}
}
function stopChanger() {
clearInterval(changerInterval);
changerInterval = 0;
}
$('.banner-nav a').mouseover(function () {
stopChanger();
setFeature(this);
return false;
});
$('.banner-nav a').mouseout(function () {
startChanger();
});
/* could implement other functions to e.g. change the period */
function setChangerPeriod() {
...
}
window.setChangerPeriod = setChangerPeriod;
...
})
I need a function that executes a function while a button is pressed and stops executing when the button is let go
$('#button').--while being held down--(function() {
//execute continuously
});
I believe something like this would work:
var timeout, clicker = $('#clicker');
clicker.mousedown(function(){
timeout = setInterval(function(){
// Do something continuously
}, 500);
return false;
});
$(document).mouseup(function(){
clearInterval(timeout);
return false;
});
See this demo: http://jsfiddle.net/8FmRd/
A small modification to the original answer:
$('#Clicker').mousedown(function () {
//do something here
timeout = setInterval(function () {
//do same thing here again
}, 500);
return false;
});
$('#Clicker').mouseup(function () {
clearInterval(timeout);
return false;
});
$('#Clicker').mouseout(function () {
clearInterval(timeout);
return false;
});
With the mouseout event on the Clicker it stops when you move your mouse out of the click area.
The reason why I suggest to do the same thing twice is to get a smoother effect. If you don't do it once before the timeout is set it will be a delay of, in this case, 500ms before something happens.
Here's a pure JavaScript implementation of the supplied solutions which has extended support for touch screens. You supply the id, action to perform (function(){}) and the interval (ms) to repeat the action. Note that this implementation will also execute the action immediately, rather than waiting for the interval to lapse.
// Configures an element to execute a function periodically whilst it holds the user's attention via a mouse press and hold.
function assertPeriodicPress(id, action, interval) {
// Listen for the MouseDown event.
document.getElementById(id).addEventListener('mousedown', function(ev) { action(); timeout = setInterval(action, interval); return false; }, false);
// Listen for mouse up events.
document.getElementById(id).addEventListener('mouseup', function(ev) { clearInterval(timeout); return false; }, false);
// Listen out for touch end events.
document.getElementById(id).addEventListener('touchend', function(ev) { clearInterval(timeout); return false; }, false);
}
$.fn.click2=function(cb,interval){
var timeout;
if(!interval) interval=100;
$(this).mousedown(function () {
var target=this;
timeout = setInterval(function(){
cb.apply(target);
}, interval);
return false;
}).mouseup(function () {
clearInterval(timeout);
return false;
}).mouseout(function () {
clearInterval(timeout);
return false;
});
}