I am using a mega menu script I got from here. It works perfectly except seeing as how I have a few of these on my page I would like there to be a delay that the user has to hold their mouse over the link before the menu opens.
I know I need to do this with a setTimeout() tag and a clearTimeout() for when the user does takes their mouse off the link. I just can not figure out where to put this. I've tried just guessing at it but no matter where I put this it seems to either break the function or not matter.
Thank you for any help anyone might be able to provide me with, it is much appreciated.
The basic idea is something like this?
var timeout;
$('#menuID').mouseenter(function(){
clearTimeout(timeout);
$(this).children().show();
}).mouseleave(function(){
timeout = setTimeout(function(){
$(this).children().hide();
},400);
});
Note that the maker used the same way as above:
"p.s: Inside the .js file, there are two variables you may wish to fine tune:"
effectduration: 300, //duration of animation, in milliseconds
delaytimer: 200, //delay after mouseout before menu should be hidden, in milliseconds
Use this function to add a delay on whatever you want
// Function declatation
var delay = (function()
{
var timer = 0;
return function(callback, ms)
{
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
usage:
delay(function()
{
// Do thing you want delayed
}, 1000 );
Replace 1000 with amount of ms you want to delay
EDIT
$("#menuitem").mouseenter(function()
{
delay(function()
{
if($(this).is(':hover'))
// Show menu
}, 1000 );
});
Related
I'm trying to make a simple text slide show in pure javascript. Below is my code so far :
let currentChangingText = 0;
function changeText() {
if (currentChangingText == changingTextsLength) currentChangingText = 0;
$changingTexts[currentChangingText].setAttribute("class", "changing-text changing-text-slide-in");
setTimeout(function() {
setTimeout(function() { // *
$changingTexts[currentChangingText].classList.remove("changing-text-slide-in");
$changingTexts[currentChangingText].classList.add("changing-text-slide-out");
}, 1000);
$changingTexts[currentChangingText].classList.add("changing-text-hide");
++currentChangingText;
changeText();
}, 2000);
}
It "worked" but I've noticed something weird. On the first iteration (when the page loaded), the code block I've marked with * doesn't run at all so the slide out effect will not apply. On the next iterations it works fine (the slide out effect apply). I can't figure out what causes it, any help would be appreciated (plus if you know a better way to do this, please tell me as well!). Thanks in advance.
https://jsfiddle.net/15u2kfr0/
the first 2000ms nothing happens because you delay it.
setTimeout(function() { // this is delay to load+2000
setTimeout(function() { //you effectively delay this to load+3000
//part1
}, 1000);
//part2
}, 2000);
you need to either delay them separately
setTimeout(part1,1000)
setTimeout(part2,2000)
or nest them correctly
setTimeout({part1, setTimeout(part2,1000)},1000)
So I'm building this modal / timed animation with slide navigation from scratch.
I have a function for the buttons that navigate the slides, and also a function to animate the frames every 5 secs. My problem is I'm not sure how to "break" the delay function if the user decides to take over by clicking the navigation buttons. As soon as the user clicks any of those buttons the delay based animation function needs to stop working.
// Timer for Animating Frames
// Need a kill timer function
var animateFramesTimer = function(){
$('#tour_1')
.delay(5000).fadeOut('fast', function() {
$('#tour_2')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_3')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_4')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_modal').fadeOut('fast');
// END
});
});
});
});
}
animateFramesTimer();
So I run animateFramesTimer and if a certain button is clicked I need the function to stop working, I tried a while loop which seemed like the correct path to go, but it kept breaking in the browser :(
var autoAnimate = true;
while(autoAnimate){
// delay animation
}
Do you know of a better way to accomplish this?
$('[id^="tour_"]').stop(true, true); // kills current animations
animateFramesTimer = function() {}; // removes function
I have a little fiddle here where I'm starting/stopping/resetting a javascript timer.
The functionality needs to be a timer runs on a page. When the timer is up, it sends a message, then restarts. The stop button will stop the timer completely.
The fiddle above has the functionality I just described, however I feel like I'm not doing this correctly. Is setTimeout the correct way to create this timer? Should I use setInterval instead?
Secondly, my reset code looks like :
var onReset = function() {
clearTimeout(timerHandle);
onStart();
};
Is there a more elegant way to reset a timer in javascript?
Thanks.
The only improvement I can offer is for you to put it all in an encapsulated object, ask if you want an example. Or if you want to keep the structure you've got then change your onStart function to this to remove a bit of un-needed code.
var onStart = function() {
timerHandle = setInterval(function() {
$("#console").append("timer fired.. <br />");
}, 2000);
};
Fiddle here http://jsfiddle.net/qx6CM/
Can anyone point me to an example of code for a page that begins to automatically scroll when the user is idle for an amount of time? I think this is slightly beyond my skill set. I think JQuery or something similar might be appropriate but I just can't seem to figure it out. I'm designing a site for the nonprofit I work for and we don't have the money to hire a programmer. I wouldn't ask anyone to code anything for me, just to point me in the right direction. Thank you so much.
Julie K.
Here is something quick and dirty that will do what you want. I currently have it set to 2 seconds idle time, but you can change that as you wish.
var now = new Date();
setInterval(function(){
var nnow = new Date();
if(nnow.getTime() - now.getTime() >= 2000)
$('body').animate({scrollTop: '+=50'}, 2000, 'linear');
}, 2000);
$(document)
.mousemove(function(){ now = new Date(); $('body').stop(); })
.keypress(function(){ now = new Date(); $('body').stop(); });
Edit: added .stop in mousemove and keypress events to stop scrolling immediately when user moves mouse or presses a key, rather than waiting for animation to complete.
jQuery would definitely help here.
You should handle the keyboard and mouse events to catch user activity.
Then, whenever you see activity, call setTimeout to make your code run 2 minutes after the activity. Save the return value of the setTimeout call in a global variable, and call clearTimeout on it before setTimeout to clear the last timeout.
For example: (Using jQuery and the scrollTo plugin)
var timeout = false;
$(document.body).bind('keydown keyup mousemove mouseup', function() {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(userIsIdle, 120000); //120,000 milliseconds
});
function userIsIdle() {
$(document.body).scrollTo('100%', 100000);
}
you could use a plugin like this, and set it to use JavaScripts setTimeout() function to trigger it, which could reset every time you detect certain user actions, such as keyDown and Click.
First you have to define what you mean by IDLE, I will assume that the user is not moving mouse for x amount of time.
Here are the steps pseudo js.
var lastTime=0;
var threshold=60000 ; // 1min
var howOftenToCheck = 1000;//1 sec
var inter = 0;
inter = setInterval(function() {
var delta=lastTime-currentTime;
if(delta>threashold){
clearInterval(inter);
window.scrollTo(xpos,ypos);
}
}, howOftenToCheck);
This should give you a general idea.
use the following jQuery functions to scroll the page's body
// Scrolling Down
$('body').animate({
scrollTop: '-=300px'
}, 2000);
// Scrolling Up
$('body').animate({
scrollTop: '+=300px'
}, 2000);
I think onBlur event is what you're looking for, so you can do like this :
<body onblur="$('html, body').animate({scrollTop:0}, 'slow');">
You can change the 0 to the vertical position where you want to scroll to.
Note: this will fire the scrolling when you go to other page or tab or where you can't see the page.
How can I reset the auto-scroll interval on my jCarouselLite carousel after some event so that it lets you look at the content for the full interval, regardless of how far along the timer was when you clicked next or previous? Right now, if I click next or previous after 9 seconds, it scrolls again after 1 second.
In the jCarouselLite source code on lines 274-277 is where the auto-scroll is implemented using setInterval. I know you can use clearInterval if you have the ID returned by setInterval, but there isn't one I can get outside of modifying the source code, and I don't want to do that.
Any ideas? Thanks!
jCarouselLite itself doesn't provide any easy way to stop the auto-scrolling, which is an easier problem then do what you seem to want (?did I understand this right: You just want the autoscroll to temporarily stop on click and then continue)
Hacky + potentially buggy way to stop the autoscroll altogether
var x; //hold interval id
$(function() {
var y = window.setInterval; //backup original setInterval function
//overwrite with new function which stores the id for us
window.setInterval = function() {
x = y(arguments[0], arguments[1]);
return x;
};
//now construct carousel
$(".anyClass").jCarouselLite({
btnNext: ".next",
btnPrev: ".prev",
auto: 500
});
//now restore original setInterval function
//as we only needed the custom one for the carousel to capture the hidden
//internal call to setInterval
window.setInterval = y;
});
$("#stopAutoScrollButton").click(function() {
clearInterval(x);
});
Real solution
As we can't get jCarouselLite to do this on its own we simulate the auto behavior ourself.
$(function() {
var autoTime = 5000; //5s
$(".anyClass").jCarouselLite({
btnNext: ".next",
btnPrev: ".prev"
});
//simulate autoscroll by simulating "click" on next link
var x = setInterval("$('.next').trigger('click');", autoTime);
//if stopAuto is clicked the autoscroll is suspended for autoTime
//no matter how far along the timer already was
$("#stopAuto").click(function() {
clearInterval(x);
x = setInterval("$('.next').trigger('click');", autoTime);
});
});
Here's a version with a pause on mouseover built-in. Works nicely.
http://github.com/cheald/jcarousel-lite
None of these answers were what I was looking for, but this is what comes up when I Google 'jcarousellite reset timer', so for the next person looking to:
Make the timer reset when you click your previous/next slide buttons
Pause the slideshow on hover
Then this is what I put together that works for me:
(function($){$.fn.jCarouselLite=function(o){o=$.extend({btnPrev:null,btnNext:null,btnGo:null,mouseWheel:false,auto:null,speed:200,easing:null,vertical:false,circular:true,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null},o||{});return this.each(function(){var running=false,animCss=o.vertical?"top":"left",sizeCss=o.vertical?"height":"width";var div=$(this),a=$("#featuredlistings a.next"),ul=$("ul",div),tLi=$("li",ul),tl=tLi.size(),v=o.visible;if(o.circular){ul.prepend(tLi.slice(tl-v-1+1).clone()).append(tLi.slice(0,v).clone());o.start+=v;}var li=$("li",ul),itemLength=li.size(),curr=o.start;div.css("visibility","visible");li.css({overflow:"hidden",float:o.vertical?"none":"left"});ul.css({margin:"0",padding:"0",position:"relative","list-style-type":"none","z-index":"1"});div.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"});var liSize=o.vertical?height(li):width(li);var ulSize=liSize*itemLength;var divSize=liSize*v;li.css({width:li.width(),height:li.height()});ul.css(sizeCss,ulSize+"px").css(animCss,-(curr*liSize));div.css(sizeCss,divSize+"px");if(o.btnPrev)$(o.btnPrev).click(function(){resetAuto(); return go(curr-o.scroll);});if(o.btnNext)$(o.btnNext).click(function(){resetAuto(); return go(curr+o.scroll);});if(o.btnGo)$.each(o.btnGo,function(i,val){$(val).click(function(){return go(o.circular?o.visible+i:i);});});if(o.mouseWheel&&div.mousewheel)div.mousewheel(function(e,d){return d>0?go(curr-o.scroll):go(curr+o.scroll);});if(o.auto){autoScroll=setInterval(function(){go(curr+o.scroll);},o.auto+o.speed);function resetAuto(){clearInterval(autoScroll);autoScroll=setInterval(function(){go(curr+o.scroll);},o.auto+o.speed);};div.hover(function(){clearInterval(autoScroll);},function(){autoScroll=setInterval(function(){go(curr+o.scroll);},o.auto+o.speed);});}function vis(){return li.slice(curr).slice(0,v);};function go(to){if(!running){if(o.beforeStart)o.beforeStart.call(this,vis());if(o.circular){if(to<=o.start-v-1){ul.css(animCss,-((itemLength-(v*2))*liSize)+"px");curr=to==o.start-v-1?itemLength-(v*2)-1:itemLength-(v*2)-o.scroll;}else if(to>=itemLength-v+1){ul.css(animCss,-((v)*liSize)+"px");curr=to==itemLength-v+1?v+1:v+o.scroll;}else curr=to;}else{if(to<0||to>itemLength-v)return;else curr=to;}running=true;ul.animate(animCss=="left"?{left:-(curr*liSize)}:{top:-(curr*liSize)},o.speed,o.easing,function(){if(o.afterEnd)o.afterEnd.call(this,vis());running=false;});if(!o.circular){$(o.btnPrev+","+o.btnNext).removeClass("disabled");$((curr-o.scroll<0&&o.btnPrev)||(curr+o.scroll>itemLength-v&&o.btnNext)||[]).addClass("disabled");}}return false;};});};function css(el,prop){return parseInt($.css(el[0],prop))||0;};function width(el){return el[0].offsetWidth+css(el,'marginLeft')+css(el,'marginRight');};function height(el){return el[0].offsetHeight+css(el,'marginTop')+css(el,'marginBottom');};})(jQuery);
Just swap it out with your current jCarouselLite script and use it just the same.
If you are able/authorized to change the plugin code:
Add a variable to save the interval id to the plugins defaults
interval: null
Search for:
if(o.auto)
Take the code which is executed here and make an internal function with it like:
function runAuto() {
setInterval(function() {
go(curr+o.scroll);
}, o.auto+o.speed);
}
Now just save the interval to your defined variable but clear it first:
function runAuto() {
clearInterval(o.interval);
o.interval = setInterval(function() {
go(curr+o.scroll);
}, o.auto+o.speed);
}
Search for the go() function in the plugin and add a runAuto(), so each time the function go is called it resets the interval.
Of course you must also add the runAuto() call to if(o.auto) so the interval starts at first.