I'm trying this below code:
$(document).ready(function() {
$("button").hover(
function() {
$(this).addClass("active");
},
function() {
$(this).removeClass("active");
}
);
});
Try this: http://plnkr.co/edit/Xlco44QPWvKEh1jb0gDf?p=preview
var button = $('button');
button.hover(
function() {
button.addClass('active');
setTimeout(function() {
button.removeClass('active');
}, 3000);
},
function() {
button.removeClass('active');
}
);
From what you said in your previous comment below, you tried setTimeout and it didn't work because of the the way you used this. The value of this inside the timeout function wasn't the same as in your outer function, so jQuery didn't match your button element.
Better to define the button once as a variable, and reuse the variable, that use repeated jQuery selectors.
UPDATE: Here's a slightly more sophisticated version that keeps the setTimeout timers from piling up:
$(function() {
var button = $('button');
var timeout = 0;
button.hover(
function() {
button.addClass('active');
timeout = setTimeout(function() {
button.removeClass('active');
timeout = 0;
}, 2000);
},
function() {
button.removeClass('active');
if (timeout) {
clearTimeout(timeout);
timeout = 0;
}
}
);
});
I have created a jQuery extention just for that! This is extremely common in web development:
jQuery.addTempClass.js
$.fn.addTempClass = function(tempClass, duration){
if( !tempClass )
return this;
return this.each(function(){
var $elm = $(this),
timer;
$elm.addClass(tempClass);
// clear any timeout, if was any
clearTimeout( $elm.data('timeout') )
timer = setTimeout(function(){
$elm.removeClass(tempClass).removeData('timeout');
}, duration || 100);
// set the timer on the element
$elm.data('timeout', timer);
});
};
Usage example:
$(document.body).addTempClass('some_class', 2000)
You can include this script as a dependency file for your build system or simply copy-paste this piece of code somewhere in your code, just after jQuery has loaded, so it will be available everywhere afterwards.
I have two div's which are absolute positioned to sit on top of each other. I'm just looking to create a simple jQuery function which fades away the div on top (.group-fcallout-b) to reveal the one underneath (.group-fcallout-a).
Here's my JS:
$(document).ready(function() {
InfiniteRotator();
});
function InfiniteRotator() {
var fadeO = setInterval(function() {
$('.group-fcallout-b').fadeOut(500);
}, 5000);
clearInterval(InfiniteRotator);
var fadeI = setInterval(function() {
$('.group-fcallout-b').fadeIn(500);
}, 5000);
}
I think the issue I'm having at the moment is that fadeIn starts immediately after fadeOut has finished - obviously I want a delay between the two functions.
JSFiddle Link: https://jsfiddle.net/02xLjh1y/11/
Many thanks!
Here is one way to achieve what I think is your goal (fiddle here):
$(document).ready(function() {
InfiniteRotator(jQuery.fn.fadeOut, jQuery.fn.fadeIn);
});
function InfiniteRotator(fadeFunc, callback) {
fadeFunc.call($('.group-fcallout-b'), 500, function() {
setTimeout(function() { InfiniteRotator(callback, fadeFunc); }, 1000);
});
}
[Edit: added a timeout before fading back the other way]
Since both fadeIn and fadeOut take an optional callback argument, you can exploit this instead of using setInterval.
N.B. I don't know whether you care or not, but the use of a capital 'I' in InfiniteRotator is a bit unusual - normally the capital letter would tend to imply that this is a constructor function, which it isn't.
It's actually a one liner:
setInterval(function(){ $('.group-fcallout-b').fadeToggle(500); }, 5000)
updated fiddle
Is this correct for you ?
See this fiddle
I changed value of timeout in the second one.
var fadeO = setInterval(function() {
$('.group-fcallout-b').fadeOut(500);
}, 5000);
clearInterval(InfiniteRotator);
var fadeI = setInterval(function() {
$('.group-fcallout-b').fadeIn(500);
}, 10000);
how about this?
$(document).ready(function() {
InfiniteRotator();
});
function InfiniteRotator() {
var flag = 1;
var fadeOut = function() {
$('.group-fcallout-b').fadeOut(500);
flag = 0;
}
var fadeIn = function() {
$('.group-fcallout-b').fadeIn(500);
flag = 1;
}
var timer = setInterval(function(){
if(flag)
fadeOut();
else
fadeIn();
}, 5000);
}
I can't figure out how to do it.
I have two separate scripts. The first one generates an interval (or a timeout) to run a specified function every x seconds, i.e. reload the page.
The other script contains actions for a button to control (pause/play) this interval.
The pitfall here is that both sides must be asyncronous (both run when the document is loaded).
How could I properly use the interval within the second script?
Here's the jsFiddle: http://jsfiddle.net/hm2d6d6L/4/
And here's the code for a quick view:
var interval;
// main script
(function($){
$(function(){
var reload = function() {
console.log('reloading...');
};
// Create interval here to run reload() every time
});
})(jQuery);
// Another script, available for specific users
(function($){
$(function(){
var $playerButton = $('body').find('button.player'),
$icon = $playerButton.children('i');
buttonAction = function(e){
e.preventDefault();
if ($(this).hasClass('playing')) {
// Pause/clear interval here
$(this).removeClass('playing').addClass('paused');
$icon.removeClass('glyphicon-pause').addClass('glyphicon-play');
}
else {
// Play/recreate interval here
$(this).removeClass('paused').addClass('playing');
$icon.removeClass('glyphicon-play').addClass('glyphicon-pause');
}
},
buttonInit = function() {
$playerButton.on('click', buttonAction);
};
buttonInit();
});
})(jQuery);
You could just create a simple event bus. This is pretty easy to create with jQuery, since you already have it in there:
// somewhere globally accessible (script 1 works fine)
var bus = $({});
// script 1
setInterval(function() {
reload();
bus.trigger('reload');
}, 1000);
// script 2
bus.on('reload', function() {
// there was a reload in script 1, yay!
});
I've found a solution. I'm sure it's not the best one, but it works.
As you pointed out, I eventually needed at least one global variable to act as a join between both scripts, and the use of a closure to overcome asyncronous issues. Note that I manipulate the button within reload, just to remark that sometimes it's not as easy as moving code outside in the global namespace:
Check it out here in jsFiddle: yay! this works!
And here's the code:
var intervalControl;
// main script
(function($){
$(function(){
var $playerButton = $('body').find('button.player'),
reload = function() {
console.log('reloading...');
$playerButton.css('top', parseInt($playerButton.css('top')) + 1);
};
var interval = function(callback) {
var timer,
playing = false;
this.play = function() {
if (! playing) {
timer = setInterval(callback, 2000);
playing = true;
}
};
this.pause = function() {
if (playing) {
clearInterval(timer);
playing = false;
}
};
this.play();
return this;
};
intervalControl = function() {
var timer = interval(reload);
return {
play: function() {
timer.play();
},
pause: function(){
timer.pause();
}
}
}
});
})(jQuery);
// Another script, available for specific users
(function($){
$(function(){
var $playerButton = $('body').find('button.player'),
$icon = $playerButton.children('i'),
interval;
buttonAction = function(e){
e.preventDefault();
if ($(this).hasClass('playing')) {
interval.pause();
$(this).removeClass('playing').addClass('paused');
$icon.removeClass('glyphicon-pause').addClass('glyphicon-play');
}
else {
interval.play();
$(this).removeClass('paused').addClass('playing');
$icon.removeClass('glyphicon-play').addClass('glyphicon-pause');
}
},
buttonInit = function() {
$playerButton.on('click', buttonAction);
interval = intervalControl();
};
buttonInit();
});
})(jQuery);
Any better suggestion is most welcome.
This is a followup to this question, where I found out how to make code be repeated every x seconds. Is it possible to make an event that can change this? I.e. I have a checkbox which is meant to control whether this is repeated or not, so I figured I'd need something like this:
$(checkbox).bind("change", function() {
switch(whether if it is ticked or not) {
case [ticked]:
// Make the code repeat, while preserving the ability to stop it repeating
case [unticked]:
// Make the code stop repeating, while preserving the ability to start again
}
});
I have no idea what I could put in the cases.
You can do it by assigning your setInterval function to a variable.
var interval = setInterval(function() { }, 1000);
and then you can stop setInterval by
clearInterval(interval);
p.s.
to start your interval you need to call var interval = setInterval(function() { }, 1000); again
You can either stop and start the interval:
var timer;
function start() {
timer = window.setInterval(function(){
// do something
}, 1000);
}
function stop() {
window.clearInterval(timer);
}
start();
$(checkbox).bind("change", function() {
if ($(this).is(':checked')) {
start();
} else {
stop();
}
});
Or you can have a flag causing the interval to skip the code:
var enabled = true;
var timer = window.setInterval(function(){
if (!enabled) {
// do something
}
}, 1000);
$(checkbox).bind("change", function() {
enabled = $(this).is(':checked');
});
function fooFunc() {
$('#foo').text(+new Date());
}
var id;
var shouldBeStopped = false;
$('input').change(function() {
if (shouldBeStopped)
clearInterval(id);
else
id = setInterval(fooFunc, 200);
shouldBeStopped = !shouldBeStopped;
});
Live DEMO
Ok with this..
$(window).scroll(function()
{
$('.slides_layover').removeClass('showing_layover');
$('#slides_effect').show();
});
I can tell when someone is scrolling from what I understand. So with that I am trying to figure out how to catch when someone has stopped. From the above example you can see I am removing a class from a set of elements while the scrolling is occurring. However, I want to put that class back on when the user stops scrolling.
The reason for this is I am intent on having a layover show while the page is scrolling to give the page a special effect I am attempting to work on. But the one class I am trying to remove while scrolling conflicts with that effect as its a transparency effect to some nature.
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
// do something
console.log("Haven't scrolled in 250ms!");
}, 250));
});
Update
I wrote an extension to enhance jQuery's default on-event-handler. It attaches an event handler function for one or more events to the selected elements and calls the handler function if the event was not triggered for a given interval. This is useful if you want to fire a callback only after a delay, like the resize event, or such.
It is important to check the github-repo for updates!
https://github.com/yckart/jquery.unevent.js
;(function ($) {
var on = $.fn.on, timer;
$.fn.on = function () {
var args = Array.apply(null, arguments);
var last = args[args.length - 1];
if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args);
var delay = args.pop();
var fn = args.pop();
args.push(function () {
var self = this, params = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(self, params);
}, delay);
});
return on.apply(this, args);
};
}(this.jQuery || this.Zepto));
Use it like any other on or bind-event handler, except that you can pass an extra parameter as a last:
$(window).on('scroll', function(e) {
console.log(e.type + '-event was 250ms not triggered');
}, 250);
http://yckart.github.com/jquery.unevent.js/
(this demo uses resize instead of scroll, but who cares?!)
Using jQuery throttle / debounce
jQuery debounce is a nice one for problems like this. jsFidlle
$(window).scroll($.debounce( 250, true, function(){
$('#scrollMsg').html('SCROLLING!');
}));
$(window).scroll($.debounce( 250, function(){
$('#scrollMsg').html('DONE!');
}));
The second parameter is the "at_begin" flag. Here I've shown how to execute code both at "scroll start" and "scroll finish".
Using Lodash
As suggested by Barry P, jsFiddle, underscore or lodash also have a debounce, each with slightly different apis.
$(window).scroll(_.debounce(function(){
$('#scrollMsg').html('SCROLLING!');
}, 150, { 'leading': true, 'trailing': false }));
$(window).scroll(_.debounce(function(){
$('#scrollMsg').html('STOPPED!');
}, 150));
Rob W suggected I check out another post here on stack that was essentially a similar post to my original one. Which reading through that I found a link to a site:
http://james.padolsey.com/javascript/special-scroll-events-for-jquery/
This actually ended up helping solve my problem very nicely after a little tweaking for my own needs, but over all helped get a lot of the guff out of the way and saved me about 4 hours of figuring it out on my own.
Seeing as this post seems to have some merit, I figured I would come back and provide the code found originally on the link mentioned, just in case the author ever decided to go a different direction with the site and ended up taking down the link.
(function(){
var special = jQuery.event.special,
uid1 = 'D' + (+new Date()),
uid2 = 'D' + (+new Date() + 1);
special.scrollstart = {
setup: function() {
var timer,
handler = function(evt) {
var _self = this,
_args = arguments;
if (timer) {
clearTimeout(timer);
} else {
evt.type = 'scrollstart';
jQuery.event.handle.apply(_self, _args);
}
timer = setTimeout( function(){
timer = null;
}, special.scrollstop.latency);
};
jQuery(this).bind('scroll', handler).data(uid1, handler);
},
teardown: function(){
jQuery(this).unbind( 'scroll', jQuery(this).data(uid1) );
}
};
special.scrollstop = {
latency: 300,
setup: function() {
var timer,
handler = function(evt) {
var _self = this,
_args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout( function(){
timer = null;
evt.type = 'scrollstop';
jQuery.event.handle.apply(_self, _args);
}, special.scrollstop.latency);
};
jQuery(this).bind('scroll', handler).data(uid2, handler);
},
teardown: function() {
jQuery(this).unbind( 'scroll', jQuery(this).data(uid2) );
}
};
})();
I agreed with some of the comments above that listening for a timeout wasn't accurate enough as that will trigger when you stop moving the scroll bar for long enough instead of when you stop scrolling. I think a better solution is to listen for the user letting go of the mouse (mouseup) as soon as they start scrolling:
$(window).scroll(function(){
$('#scrollMsg').html('SCROLLING!');
var stopListener = $(window).mouseup(function(){ // listen to mouse up
$('#scrollMsg').html('STOPPED SCROLLING!');
stopListner(); // Stop listening to mouse up after heard for the first time
});
});
and an example of it working can be seen in this JSFiddle
ES6 style with checking scrolling start also.
function onScrollHandler(params: {
onStart: () => void,
onStop: () => void,
timeout: number
}) {
const {onStart, onStop, timeout = 200} = params
let timer = null
return (event) => {
if (timer) {
clearTimeout(timer)
} else {
onStart && onStart(event)
}
timer = setTimeout(() => {
timer = null
onStop && onStop(event)
}, timeout)
}
}
Usage:
yourScrollableElement.addEventListener('scroll', onScrollHandler({
onStart: (event) => {
console.log('Scrolling has started')
},
onStop: (event) => {
console.log('Scrolling has stopped')
},
timeout: 123 // Remove to use default value
}))
You could set an interval that runs every 500 ms or so, along the lines of the following:
var curOffset, oldOffset;
oldOffset = $(window).scrollTop();
var $el = $('.slides_layover'); // cache jquery ref
setInterval(function() {
curOffset = $(window).scrollTop();
if(curOffset != oldOffset) {
// they're scrolling, remove your class here if it exists
if($el.hasClass('showing_layover')) $el.removeClass('showing_layover');
} else {
// they've stopped, add the class if it doesn't exist
if(!$el.hasClass('showing_layover')) $el.addClass('showing_layover');
}
oldOffset = curOffset;
}, 500);
I haven't tested this code, but the principle should work.
function scrolled() {
//do by scroll start
$(this).off('scroll')[0].setTimeout(function(){
//do by scroll end
$(this).on('scroll',scrolled);
}, 500)
}
$(window).on('scroll',scrolled);
very small Version with start and end ability
This detects the scroll stop after 1 milisecond (or change it) using a global timer:
var scrollTimer;
$(window).on("scroll",function(){
clearTimeout(scrollTimer);
//Do what you want whilst scrolling
scrollTimer=setTimeout(function(){afterScroll()},1);
})
function afterScroll(){
//I catched scroll stop.
}
Ok this is something that I've used before.
Basically you look a hold a ref to the last scrollTop().
Once your timeout clears, you check the current scrollTop() and if they are the same, you are done scrolling.
$(window).scroll((e) ->
clearTimeout(scrollTimer)
$('header').addClass('hidden')
scrollTimer = setTimeout((() ->
if $(this).scrollTop() is currentScrollTop
$('header').removeClass('hidden')
), animationDuration)
currentScrollTop = $(this).scrollTop()
)
please check the jquery mobile scrollstop event
$(document).on("scrollstop",function(){
alert("Stopped scrolling!");
});
For those Who Still Need This Here Is The Solution
$(function(){
var t;
document.addEventListener('scroll',function(e){
clearTimeout(t);
checkScroll();
});
function checkScroll(){
t = setTimeout(function(){
alert('Done Scrolling');
},500); /* You can increase or reduse timer */
}
});
This should work:
var Timer;
$('.Scroll_Table_Div').on("scroll",function()
{
// do somethings
clearTimeout(Timer);
Timer = setTimeout(function()
{
console.log('scrolling is stop');
},50);
});
Here is how you can handle this:
var scrollStop = function (callback) {
if (!callback || typeof callback !== 'function') return;
var isScrolling;
window.addEventListener('scroll', function (event) {
window.clearTimeout(isScrolling);
isScrolling = setTimeout(function() {
callback();
}, 66);
}, false);
};
scrollStop(function () {
console.log('Scrolling has stopped.');
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
</body>
</html>