I have some javascript code that fires a click event when the user scrolls up or down past a specific element (.closemenu). I'm using this to automatically open and close a header menu when the user scrolls the page.
The problem I have is that this is firing too many times and causing lagging and glitching on scroll, I've found this post which shows the usage of throttling for scroll events but I can't get it to work with my current javascript which is:
<script>
jQuery(window).scroll(function() {
var hT = jQuery('.closemenu').offset().top,
hH = jQuery('.closemenu').outerHeight(),
wH = jQuery(window).height(),
wS = jQuery(this).scrollTop();
console.log((hT-wH) , wS);
if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
jQuery('.menu-bar').trigger('click');
}
});
</script>
I've tried a few variations but I can't work out what the issue is, does anyone know how can I throttle this event by 30ms or so?
Try if the below code works for you. You can change the ES6 throttle function to ES5 if your browser doesn't support ES6.
var func = function(){
var hT = jQuery('.closemenu').offset().top,
hH = jQuery('.closemenu').outerHeight(),
wH = jQuery(window).height(),
wS = jQuery(this).scrollTop();
console.log((hT-wH) , wS);
if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
jQuery('.menu-bar').trigger('click');
}
}
jQuery(window).scroll(function() {
throttle(func,30);
});
const throttle = (func, limit) => {
let inThrottle
return function() {
const args = arguments
const context = this
if (!inThrottle) {
func.apply(context, args)
inThrottle = true
setTimeout(() => inThrottle = false, limit)
}
}
}
WORKING ANSWER:
<script>
jQuery(window).scroll(function() {
var hT = jQuery('.closemenu').offset().top,
hH = jQuery('.closemenu').outerHeight(),
wH = jQuery(window).height(),
wS = jQuery(this).scrollTop();
console.log((hT-wH) , wS);
if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
jQuery('.menu-bar').trigger('click');
}
function throttle(fn, threshhold, scope) {
threshhold || (threshhold = 1250);
var last,
deferTimer;
return function () {
var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
});
</script>
Related
I am using the following function in a single page application in Angular. When I click on the menu item, I scroll to the relevant div.
scroll (el) {
this.sharedService.isClicked.next(true);
el.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
How do I check if the element has finished scrolling? I want to avoid the setTimeout function.
hope this helps..
var scrollIntoviewCompleted = false;
var currentVisible = false;
var onceVisible = false;
$(window).scroll(function(){
$.fn.isOnScreen = function(){
var element = this.get(0);
var bounds = element.getBoundingClientRect();
return bounds.top < window.innerHeight && bounds.bottom > 0;
}
if ($('.targetdiv').isOnScreen()) {
currentVisible = true;
onceVisible =true;
}
else
{
currentVisible = false;
}
if(onceVisible == true && currentVisible == false){
scrollIntoviewCompleted = true;
console.log("scrollIntoViewCompleted");
}
});
Based on an answer in this question I was able to make this for my tests... and this assumes that you are #Injecting window into your angular components
let win: Window;
const onScrollEnd = (fn: () => void): void => {
let scrollTimeout: number | undefined;
const listener = (): void => {
win.clearTimeout(scrollTimeout);
scrollTimeout = win.setTimeout(() => {
win.removeEventListener('scroll', listener);
fn();
}, 100);
};
win.addEventListener('scroll', listener);
};
beforeEach(() => {
//Standard component test setup stuff goes here...
win = TestBed.get('Window');
});
And then in my test I can do this:
it('should scroll the window down when...', (done: DoneFn) => {
component.shouldScroll = true;
fixture.detectChanges();
onScrollEnd(() => {
expect(win.scrollY).toBeGreaterThan(0);
done();
});
});
This worked for me (I declare this snippet public domain, feel free to re-use):
scrollAndDo = function(currPageXOffset,currPageYOffset) {
$('#SomeElement')[0].scrollIntoView({behavior: 'smooth',block:'nearest',inline: 'nearest'});
currPageXOffset = window.pageXOffset;
currPageYOffset = window.pageYOffset;
var scrollDone = setInterval(function () {
if ( currPageXOffset == window.pageXOffset && currPageYOffset == window.pageYOffset ) {
clearInterval(scrollDone);
console.log('I have finished scrolling');
}
currPageXOffset = window.pageXOffset;
currPageYOffset = window.pageYOffset;
},50);
};
scrollAndDo();
Need some help with my code, I can't get my alerts to work with my countdown timer. They should be alerting at 4,3,2 minutes left on the timer. I currently can't get the alerts to fire at all, sometimes they would fire but each second after 4, the alert for "4" would fire. I need it to just go once... Any help would be appreciated
Heres my script
var running=false
var endTime=null
var timerID=null
function startTimer(){
running=true
now=new Date()
now=now.getTime()
endTime=now+(1000*60*5)
showCountDown()
}
function showCountDown(){
var now=new Date()
now=now.getTime()
if (endTime-now<=239990 && endTime-now>240010){alert("4")};
if (endTime-now<=179990 && endTime-now>180010){alert("3")};
if (endTime-now<=119990 && endTime-now>120010){alert("2")};
if (endTime-now<=0){
stopTimer()
alert("Time is up. Put down pencils")
} else {
var delta=new Date(endTime-now)
var theMin=delta.getMinutes()
var theSec=delta.getSeconds()
var theTime=theMin
theTime+=((theSec<10)?":0" : ":")+theSec
document.forms[0].timerDisplay.value=theTime
if (running){
timeID=setTimeout("showCountDown()",1000)
}
}
}
function stopTimer(){
clearTimeout(timeID)
running=false
document.forms[0].timerDisplay.value="0.00"
}
Update, Sorry meant minutes instead of seconds
Update 2: Change the ifs, now they fire but keep firing after the 4 second mark
if (endTime-now<=240010 && endTime-now<=239990){alert("4")};
if (endTime-now<=180010 && endTime-now<=179990){alert("3")};
if (endTime-now<=120010 && endTime-now<=119990){alert("2")};
Why are you calling clearTimeout? setTimeout invokes its callback only once. There is no need to clear it. Also you could just have a variable that stores the minutes until the end of the countdown and decrement that by one in each iteration.
The simplest solution might look like this
function startTimer(minutesToEnd) {
if(minutesToEnd > 0) {
if(minutesToEnd <= 4) {
console.log(minutesToEnd);
}
setTimeout(startTimer, 60000, minutesToEnd - 1);
} else {
console.log("Time is up. Put down pencils")
}
}
I actually spent some time working on this. I have no idea if this is what you wanted, but I created a timer library. I have a working demo for you. I had fun making this. Let me know what you think:
JS:
(function () {
var t = function (o) {
if (!(this instanceof t)) {
return new t(o);
}
this.target = o.target || null;
this.message = o.message;
this.endMessage = o.endMessage;
//setInterval id
this.si = -1;
//Initial start and end
this.startTime = null;
this.endTime = null;
this.interTime = null;
this.duration = o.duration || 1000 * 60 * 5;
//looping speed miliseconds it is best to put the loop at a faster speed so it doesn't miss out on something
this.loop = o.loop || 300;
//showing results miliseconds
this.show = o.show || 1000;
};
t.fn = t.prototype = {
init: function () {}
};
//exporting
window.t = t;
})();
//Timer Functions ---
t.fn.start = function () {
this.startTime = new Date();
this.interTime = this.startTime.getTime();
this.endTime = new Date().setMilliseconds(this.startTime.getMilliseconds() + this.duration);
//returns undefined... for some reason.
console.log(this.endTime);
var $this = this;
this.writeMessage(this.duration);
this.si = setInterval(function () {
var current = new Date(),
milli = current.getTime();
if (milli - $this.interTime >= $this.show) {
var left = $this.endTime- milli;
if (left <= 0) {
$this.stop();
} else {
$this.interTime = milli;
$this.writeMessage(left);
}
}
}, this.loop);
return this;
};
t.fn.writeMessage = function(left){
this.target.innerHTML = this.message + ' ' + Math.floor(left / 1000);
return this;
};
t.fn.stop = function () {
//stopping the timer
clearInterval(this.si);
this.target.innerHTML = this.endMessage;
return this;
};
//Not chainable
t.fn.isRunning = function () {
return this.timer > -1;
};
var timer = t({
target: document.getElementById('results'),
loop: 50,
duration: 10000,
show: 1000, //default is at 1000 miliseconds
message: 'Time left: ', //If this is ommited then only the time left will be shown
endMessage: 'Time is up. Put down your pencils'
}).start();
document.getElementById('stop').onclick = function(){
timer.stop();
};
HTML:
<div id="results"></div>
<button id="stop">Stop</button>
Demo here
Update: I added some stuff
Demo 2
Update 2: I fixed the bug where 10 would hop straight to 8
Demo 3
I'm using Zepto.js on a current project. Zepto doesn't support the scrollTop() method that jQuery has in it.
Is it possible to kind of extend Zepto to work with scrollTop() too?
Update: All I want is to create my own small and simple "animated scroll" function like I have used before with jQuery. See the working example here. However I have no idea how to make the same function work without the scrollTop() function available in Zepto.js.
scrollTop isn't animatable using Zepto's .animate method, as it uses CSS transitions.
Try something like this: http://jsfiddle.net/DVDLM/5/
function scroll(scrollTo, time) {
var scrollFrom = parseInt(document.body.scrollTop),
i = 0,
runEvery = 5; // run every 5ms
scrollTo = parseInt(scrollTo);
time /= runEvery;
var interval = setInterval(function () {
i++;
document.body.scrollTop = (scrollTo - scrollFrom) / time * i + scrollFrom;
if (i >= time) {
clearInterval(interval);
}
}, runEvery);
}
$('#trigger').click(function () {
scroll('600px', 500);
});
EDIT: I added a runEvery variable, which specifies how often the interval should be ran. The lower this is, the smoother the animation is, but it could affect performance.
EDIT2: I think I misread the question. Here is the answer to the new question:
$.zepto.scrollTop = function (pixels) {
this[0].scrollTop = pixels;
};
dont want to steel nobody work so here is the short answer
Porting from jQuery to Zepto
Use the DOM native scrollTop property:
$('#el')[0].scrollTop = 0;
(function ($) {
['width', 'height'].forEach(function(dimension) {
var offset, Dimension = dimension.replace(/./, function(m) { return m[0].toUpperCase() });
$.fn['outer' + Dimension] = function(margin) {
var elem = this;
if (elem) {
var size = elem[dimension]();
var sides = {'width': ['left', 'right'], 'height': ['top', 'bottom']};
sides[dimension].forEach(function(side) {
if (margin) size += parseInt(elem.css('margin-' + side), 10);
});
return size;
}
else {
return null;
}
};
});
["Left", "Top"].forEach(function(name, i) {
var method = "scroll" + name;
function isWindow( obj ) {
return obj && typeof obj === "object" && "setInterval" in obj;
}
function getWindow( elem ) {
return isWindow( elem ) ? elem : elem.nodeType === 9 ? elem.defaultView || elem.parentWindow : false;
}
$.fn[method] = function( val ) {
var elem, win;
if (val === undefined) {
elem = this[0];
if (!elem) {
return null;
}
win = getWindow(elem);
// Return the scroll offset
return win ? ("pageXOffset" in win) ? win[i ? "pageYOffset" : "pageXOffset"] :
win.document.documentElement[method] ||
win.document.body[method] :
elem[method];
}
// Set the scroll offset
this.each(function() {
win = getWindow(this);
if (win) {
var xCoord = !i ? val : $(win).scrollLeft();
var yCoord = i ? val : $(win).scrollTop();
win.scrollTo(xCoord, yCoord);
}
else {
this[method] = val;
}
});
}
});
})(Zepto);
The answer is simple, Zepto dose not use timeout style animation, it uses css3, so here is a basic implementation for a scroll function:
HTML:
Animated Scroll
Hello You
CSS:
#page { height:5000px; position:relative; }
#element { position:absolute; top:600px }
JS:
function scroll(selector, animate, viewOffset) {
$('body').scrollToBottom (600, '800');
}
$('#trigger').click(function(e) {
e.preventDefault();
scroll( $('#element'), true, 30 );
});
$.fn.scrollToBottom = function(scrollHeight ,duration) {
var $el = this;
var el = $el[0];
var startPosition = el.scrollTop;
var delta = scrollHeight - startPosition;
var startTime = Date.now();
function scroll() {
var fraction = Math.min(1, (Date.now() - startTime) / duration);
el.scrollTop = delta * fraction + startPosition;
if(fraction < 1) {
setTimeout(scroll, 10);
}
}
scroll();
};
Note that version 1.0 of Zeptos now supports scrollTop(). See Documentation:
http://zeptojs.com/#scrollTop
Is there a way to bind to a double-tap event (in a single line of code) for mobile safari? Or, the alternative is to implement it intercepting two single-tap events that happened in some short given time (example: http://appcropolis.com/blog/implementing-doubletap-on-iphones-and-ipads/)?
Short answer: you must implement via two clicks.
Actual answer: Here is a jQuery-free implementation of double-tap for mobile safari which only requires one line of code (to enable dblclick event):
https://gist.github.com/2927073
In addition, you will likely need to disable mobile Safari's default zoom with this meta tag:
<meta name="viewport" content="width=device-width,user-scalable=no" />
If you want to have working double click both on browser and IOS platform, you should have the following code:
jQuery.event.special.dblclick = {
setup: function(data, namespaces) {
var agent = navigator.userAgent.toLowerCase();
if (agent.indexOf('iphone') >= 0 || agent.indexOf('ipad') >= 0 || agent.indexOf('ipod') >= 0) {
var elem = this,
$elem = jQuery(elem);
$elem.bind('touchend.dblclick', jQuery.event.special.dblclick.handler);
} else {
var elem = this,
$elem = jQuery(elem);
$elem.bind('click.dblclick', jQuery.event.special.dblclick.handler);
}
},
teardown: function(namespaces) {
var agent = navigator.userAgent.toLowerCase();
if (agent.indexOf('iphone') >= 0 || agent.indexOf('ipad') >= 0 || agent.indexOf('ipod') >= 0) {
var elem = this,
$elem = jQuery(elem);
$elem.unbind('touchend.dblclick');
} else {
var elem = this,
$elem = jQuery(elem);
$elem.unbind('click.dblclick', jQuery.event.special.dblclick.handler);
}
},
handler: function(event) {
var elem = event.target,
$elem = jQuery(elem),
lastTouch = $elem.data('lastTouch') || 0,
now = new Date().getTime();
var delta = now - lastTouch;
if (delta > 20 && delta < 500) {
$elem.data('lastTouch', 0);
$elem.trigger('dblclick');
} else {
$elem.data('lastTouch', now);
}
}
};
Try it here:
http://jsfiddle.net/UXRF8/
Override dblclick event and use bind, live, on, delegate like for any other event:
jQuery.event.special.dblclick = {
setup: function(data, namespaces) {
var elem = this,
$elem = jQuery(elem);
$elem.bind('touchend.dblclick', jQuery.event.special.dblclick.handler);
},
teardown: function(namespaces) {
var elem = this,
$elem = jQuery(elem);
$elem.unbind('touchend.dblclick');
},
handler: function(event) {
var elem = event.target,
$elem = jQuery(elem),
lastTouch = $elem.data('lastTouch') || 0,
now = new Date().getTime();
var delta = now - lastTouch;
if(delta > 20 && delta<500){
$elem.data('lastTouch', 0);
$elem.trigger('dblclick');
}else
$elem.data('lastTouch', now);
}
};
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I can't for the life of me figure out why loading this page...
http://polyphonic.hannahkingdev.com/work/cowboys-angels or any other video page sometimes causes the browser to hang and then prompts me to stop the script that is causing the browser to slowdown.
If the video is left to run, by the time you go to close the page, the browser is pretty unresponsive. This is the same in FFox, Safari & Chrome.
Any help finding the memory leak would be most appreciated. I am completely stumped on this one.
Many thanks
var $ = jQuery.noConflict();
$(document).ready(initPage);
// -- Init -- //
function initPage() {
resizeWork();
//hoverWorkImg();
};
// -- Pageload -- //
$(document).ready(function() {
$(".animsition").animsition({
inClass: 'overlay-slide-in-left',
outClass: 'overlay-slide-out-left',
inDuration: 1500,
outDuration: 800,
linkElement: 'a:not([target="_blank"]):not([href^=#]):not([href^=mailto]:not([href^=tel])',
loading: true,
loadingParentElement: 'body', //animsition wrapper element
loadingClass: 'animsition-loading',
loadingInner: '', // e.g '<img src="loading.svg" />'
timeout: false,
timeoutCountdown: 5000,
onLoadEvent: true,
browser: [ 'animation-duration', '-webkit-animation-duration'],
overlay : true,
overlayClass : 'animsition-overlay-slide',
overlayParentElement : 'body',
transition: function(url){ window.location.href = url; }
});
});
// -- Navigation -- //
if (document.getElementById('menu-button') !=null) {
var button = document.getElementById('menu-button');
var menu = document.getElementById('menu-main-navigation');
var menuPos = window.innerHeight;
var menuFixed = false;
button.addEventListener('click', function(ev){
ev.preventDefault();
menu.classList.toggle('navigation--isOpen');
button.classList.toggle('navigation-button--isOpen');
})
updateMenuPosition();
window.addEventListener('resize', updateMenuPosition);
// -- Highlight nav -- /
var $navigationLinks = $('#menu-main-navigation > li > a');
var $sections = $($("section").get().reverse());
var sectionIdTonavigationLink = {};
$sections.each(function() {
var id = $(this).attr('id');
sectionIdTonavigationLink[id] = $('#menu-main-navigation > li > a[href="#' + id + '"]');
});
function throttle(fn, interval) {
var lastCall, timeoutId;
return function () {
var now = new Date().getTime();
if (lastCall && now < (lastCall + interval) ) {
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
lastCall = now;
fn.call();
}, interval - (now - lastCall) );
} else {
lastCall = now;
fn.call();
}
};
}
function highlightNavigation() {
var scrollPosition = $(window).scrollTop();
$sections.each(function() {
var currentSection = $(this);
var sectionTop = currentSection.offset().top;
if (scrollPosition >= sectionTop) {
var id = currentSection.attr('id');
var $navigationLink = sectionIdTonavigationLink[id];
if (!$navigationLink.hasClass('active')) {
$navigationLinks.removeClass('active');
$navigationLink.addClass('active');
}
return false;
}
});
}
$(window).scroll( throttle(highlightNavigation,100) );
}
function updateMenuPosition(){
if(menuFixed){
menu.classList.remove('navigation--white');
menuPos = menu.offsetTop;
menu.classList.add('navigation--white');
} else {
menuPos = menu.offsetTop;
}
updateMenuAttachment();
}
updateMenuAttachment();
window.addEventListener('scroll', updateMenuAttachment);
function updateMenuAttachment(){
var scrollPos = document.documentElement.scrollTop || document.body.scrollTop;
if(!menuFixed && scrollPos >= window.innerHeight - 200){
menu.classList.add('navigation--white');
menuFixed = true;
} else if(menuFixed && scrollPos < window.innerHeight - 200){
menu.classList.remove('navigation--white');
menuFixed = false;
}
}
// -- Smooth scroll to anchor -- /
$('a[href*="#"]')
.not('[href="#"]')
.not('[href="#0"]')
.click(function(event) {
if (
location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
&&
location.hostname == this.hostname
) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (this.hash=="#work") {;
var offsetT = (target.offset().top)-90;
} else {
var offsetT = (target.offset().top);
}
if (target.length) {
event.preventDefault();
$('html, body').animate({
scrollTop: offsetT
}, 1000, function() {
});
}
}
});
// -- Back to top -- /
jQuery(document).ready(function($){
var offset = 300,
offset_opacity = 1200,
scroll_top_duration = 700,
$back_to_top = $('.cd-top');
$(window).scroll(function(){
( $(this).scrollTop() > offset ) ? $back_to_top.addClass('cd-is-visible') : $back_to_top.removeClass('cd-is-visible cd-fade-out');
if( $(this).scrollTop() > offset_opacity ) {
$back_to_top.addClass('cd-fade-out');
}
});
$back_to_top.on('click', function(event){
event.preventDefault();
$('body,html').animate({
scrollTop: 0 ,
}, scroll_top_duration
);
});
});
// -- Animate -- /
new WOW().init();
// -- Inline all SVGs -- /
jQuery('img.svg').each(function(){
var $img = jQuery(this);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');
var imgURL = $img.attr('src');
jQuery.get(imgURL, function(data) {
// Get the SVG tag, ignore the rest
var $svg = jQuery(data).find('svg');
// Add replaced image's ID to the new SVG
if(typeof imgID !== 'undefined') {
$svg = $svg.attr('id', imgID);
}
// Add replaced image's classes to the new SVG
if(typeof imgClass !== 'undefined') {
$svg = $svg.attr('class', imgClass+' replaced-svg');
}
// Remove any invalid XML tags as per http://validator.w3.org
$svg = $svg.removeAttr('xmlns:a');
// Check if the viewport is set, if the viewport is not set the SVG wont't scale.
if(!$svg.attr('viewBox') && $svg.attr('height') && $svg.attr('width')) {
$svg.attr('viewBox', '0 0 ' + $svg.attr('height') + ' ' + $svg.attr('width'))
}
// Replace image with new SVG
$img.replaceWith($svg);
}, 'xml');
});
// -- work grid -- /
function resizeWork() {
var div = $('.work article');
div.css('height', div.width() / 1.9);
}
function hoverWorkImg() {
$('article a').on('mouseenter', function () {
$(this).find('.imagehover:hidden').fadeIn(700);
$(this).find('.second:hidden').fadeIn(700);
$(this).find('.first:visible').fadeOut(700);
})
$('article a').on('mouseleave', function () {
$(this).find('.imagehover:visible').fadeOut(700);
$(this).find('.second:visible').fadeOut(700);
$(this).find('.first:hidden').fadeIn(700);
})
}
// -- Video Page -- /
function playVideoInPage() {
showModal(false);
initPlayer();
startPlay();
}
var $video,
$playPauseButton,
$muteButton,
$seekBar,
isMouseMove=false,
$timing;
function showModal(html) {
if (html !== false) {
$('.work-video').html(html).fadeIn();
}
else {
$('.work-video').fadeIn();
}
hidePlayerControls();
}
function initPlayer() {
$('#video').css('height', $(window).height());
$video = $('.video-container'),
$playPauseButton = $('#play-pause'),
$muteButton = $('#mute'),
$seekBar = $('#seek-bar'),
$timing = $('.timing');
/*setTimeout('showPlayerControls()', 1500);*/
$playPauseButton.on('click', function () {
if ($video.get()[0].paused == true) {
$video.get()[0].play();
$playPauseButton.removeClass('paused');
}
else {
$video.get()[0].pause();
$playPauseButton.addClass('paused');
$timing.stop(true, true);
}
})
$muteButton.on('click', function () {
if ($video.get()[0].muted == false) {
$video.get()[0].muted = true;
$muteButton.addClass('muted');
}
else {
$video.get()[0].muted = false;
$muteButton.removeClass('muted');
}
})
$seekBar.on("click", function (e) {
var x = e.pageX - $(this).offset().left,
widthForOnePercent = $seekBar.width() / 100,
progress = x / widthForOnePercent,
goToTime = progress * ($video.get()[0].duration / 100);
goToPercent(progress)
$video.get()[0].currentTime = goToTime;
});
$video.get()[0].addEventListener("timeupdate", function () {
var value = (100 / $video.get()[0].duration) * $video.get()[0].currentTime;
goToPercent(value)
});
}
function startPlay() {
$playPauseButton.click();
}
function goToPercent(value) {
$timing.css('width', value + '%');
}
function showPlayerControls() {
$('.controls').fadeIn();
isMouseMove=true;
}
function hidePlayerControls() {
$('.controls').fadeOut();
}
function hidePlayerControls() {
setInterval(function() {
if (!isMouseMove) {
hidePlayerControls();
}
isMouseMove=false;
}, 4000);
$(document).mousemove(function (event) {
isMouseMove=true;
showPlayerControls();
});
}
The most likely cause is this code here:
function hidePlayerControls() {
setInterval(function() {
if (!isMouseMove) {
hidePlayerControls();
}
isMouseMove=false;
}, 4000);
so every 4 seconds you start a new interval (interval = repeat until cancelled).
In the first case, you might like to change this to setTimeout
function hidePlayerControls() {
setTimeout(function() {
if (!isMouseMove) {
hidePlayerControls();
}
isMouseMove=false;
}, 4000);
In the second, you could change this to cancel the previous timeout when the mouse moves - this is termed debouncing - though usually with a shorter interval, the principle is the same.
As a general debugging tip, liberally add console.log statements and watch your browser console (there are other ways, this is a basic debugging first-step), eg:
function hidePlayerControls() {
console.log("hidePlayerControls() called");
setInterval(function() {
console.log("hidePlayerControls - interval triggered", isMouseMove);
if (!isMouseMove) {
hidePlayerControls();
}
isMouseMove=false;
}, 4000);
to see just how many times this gets called