How to cancel function using clearTimeout()? - javascript

How to cancel function using clearTimeout() when stay bottom page less than 4 sec.?
When stay at bottom page 4 sec, will alert, it's OK ^^
But when stay at bottom page less than 4 sec, then scroll to top page, Why it's will be alert too
<script src="http://code.jquery.com/jquery-1.7.2.js"></script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<script>
$(window).scroll(function(){
var height = $('#idpage').height();
var scroll_top = $(this).scrollTop();
if(($(window).scrollTop() + $(window).height() == $(document).height())){
var timer = setTimeout(function() {
alert("bottom");
}, 4000);
}
else{
clearTimeout(timer);
}
});
</script>

You have declared timer as a local variable so every time the scroll handler is called a new variable reference is used. Instead you need to preserve the value of the previous timer so you need to declare the variable outside the scope of the scroll handler like
var timer;
$(window).scroll(function () {
var height = $('#idpage').height();
var scroll_top = $(this).scrollTop();
if (($(window).scrollTop() + $(window).height() == $(document).height())) {
timer = setTimeout(function () {
alert("bottom");
}, 4000);
} else {
clearTimeout(timer);
}
});

You need to define timer variable on the top of scroll event.
var timer = 0;
$(window).scroll(function(){
var height = $('#idpage').height();
var scroll_top = $(this).scrollTop();
if(($(window).scrollTop() + $(window).height() == $(document).height())){
var timer = setTimeout(function() {
}, 4000);
}
else{
if ( timer) {
console.log(timer);
clearTimeout(timer);
}
}
});

Related

How to combine .with() and .resize() in one script

Can you help me with the following?
I have this working javascript code.
This code makes the bootstrap columns in a row all an equal height for screens with a bigger width than 640px.
if($(window).width() >= 640){
$(document).ready(function () {
$(".row").each(function () {
var highestBox = 0;
$(".col", this).each(function () {
if ($(this).height() > highestBox) highestBox = $(this).height();
});
$(".col", this).height(highestBox);
});
});
}
Problem
The problem is that if I resize the window from less than 640px to more than 640px, I have to refresh the page in order to see the changes. I'd like a script that automatically checks the window size. I think the .resize() function can help me with this but I can't figure out how to implement it.
You could implement it as follows. Put your code inside a function, let's call it resizeMe() .Then:
var rtime,
timeout = false,
waitingTime = 200,
resizeFinished = function () {
if (new Date() - rtime < waitingTime) {
window.setTimeout(resizeFinished, waitingTime);
} else {
timeout = false;
if ($(window).width() >= 640) {
resizeMe();
}
}
};
$(window).resize(function () {
rtime = new Date();
if (timeout === false) {
timeout = true;
window.setTimeout(resizeFinished, waitingTime);
}
}).resize();
With this function, your function resizeMe() is fired only when the resizing process has finished. That way it is assured that resizeMe()isn't fired at every mouse move but only if waitingTime is reached (200ms). This is quite important for performance. (Thanks to urban pointing at)
You could use following snippet, using window.matchMedia() (support & polyfill) method and binding handler in load/resize window events:
$(window).on('load resize', function() {
clearTimeout(this.resizeTimeout);
this.resizeTimeout = setTimeout(function() {
if (window.matchMedia("(min-width: 640px)").matches) {
$(".row").each(function() {
var highestBox = Math.max.apply(null, $(this).find('.box').map(function() {
return this.clientHeight; // or $(this).height()
}));
$(this).find('.box').height(highestBox);
});
}
}, 50);
});
EDIT Adding debouncing regarding good point done in #Daenu's answer
just make a function and pass it to window
function resizeMe(){
if($(window).width() >= 640){
$(document).ready(function () {
$(".row").each(function () {
var highestBox = 0;
$(".col", this).each(function () {
if ($(this).height() > highestBox) highestBox = $(this).height();
});
$(".col", this).height(highestBox);
});
});
}
}
then attach an event to window and pass your function
window.addEventListener("resize", resizeMe);
you need to put the
$(document).ready(function () on the top before the if($(window).width() >= 640)
you can use
$( window ).resize(function() function
Based on #Daenu's answer. A compressed/simplified version that is reusing the same timeout:
$(function(){
timeout = null
waitingTime = 200
$(window).resize(function(){
// Clear old timeout
if (timeout)
clearTimeout(timeout)
// Set new
timeout = setTimeout(resizeMe, waitingTime);
})
})
function resizeMe(){
$(".row").each(function () {
var highestBox = 0;
$(".col", this).each(function () {
if ($(this).height() > highestBox) highestBox = $(this).height();
});
$(".col", this).height(highestBox);
});
}
The idea is that if resize is fired while there is an active timeout, we cancel the old and re-schedule a new one
Fiddle: https://jsfiddle.net/hq1jd47v/2/

Autoscroll with JavaScript console in browser

I know the scrollBy functions but is it possible to scroll down a web page with a command typed in the JavaScript console, so that the page automatically scrolls with the passed parameters?
Typing the function
function pageScroll() {
window.scrollBy(0,50); // horizontal and vertical scroll increments
scrolldelay = setTimeout('pageScroll()',100); // scrolls every 100 milliseconds
}
and then calling it does nothing in Chrome.
Give this a try; I use it myself often.
(function() {
var intervalObj = null;
var retry = 0;
var clickHandler = function() {
console.log("Clicked; stopping autoscroll");
clearInterval(intervalObj);
document.body.removeEventListener("click", clickHandler);
}
function scrollDown() {
var scrollHeight = document.body.scrollHeight,
scrollTop = document.body.scrollTop,
innerHeight = window.innerHeight,
difference = (scrollHeight - scrollTop) - innerHeight
if (difference > 0) {
window.scrollBy(0, difference);
if (retry > 0) {
retry = 0;
}
console.log("scrolling down more");
} else {
if (retry >= 3) {
console.log("reached bottom of page; stopping");
clearInterval(intervalObj);
document.body.removeEventListener("click", clickHandler);
} else {
console.log("[apparenty] hit bottom of page; retrying: " + (retry + 1));
retry++;
}
}
}
document.body.addEventListener("click", clickHandler);
intervalObj = setInterval(scrollDown, 1000);
})()
It might show you an error "too much recursion"
You should try setInterval() instead of setTimeout(). Check this sample code for that.
setInterval(function(){
window.scrollBy(0,50);
},100);

jquery fire event after timeout

I've implemented auto page scrolling using the jQuery plugin datatables.
I'm attempting to add two buttons, one that stops the auto scrolling and one that starts it again. I've gotten this working, but I want it to begin scrolling again if the page has been stopped for a period of time. Here is what I have tried:
var refreshRate = 5;
var totalPages = 0;
var currentPage = 0;
var upTime = 0;
$('document').ready(function(){
var interval = window.setInterval('$("#start").click()',refreshRate);
$("#start").click(function(){
function start(){
clearInterval(timeout);
$("#stop").show();
$("#start").hide();
currentPage = table.api().page.info().page + 1;
totalPages = table.api().page.info().pages;
table.api().ajax.reload(function(json){
if (currentPage != totalPages){
table.api().page('next').draw(false);
}
else{
table.api().page('first').draw(false);
}
});
upTime = upTime + (refreshRate / 1000);
clearInterval(interval);
interval = setInterval('$("#start").click()', refreshRate);
}
start();
});
$("#stop").click(function(){
$("#stop").hide();
$("#start").show();
timeout();
clearInterval(interval);
});
//call start on doc ready to auto start scrolling
start();
function timeout(){
var timeout = window.setInterval(function(){
start();
}, 10000);
}
});
As you can see I am attempting to call the start() function embedded within the button click after a 10 second timeout. I am also getting a TypeError when I call start() at DOM ready to begin page scrolling.
Uncaught TypeError: object is not a function
But besides the error it scrolls as it should.
Any assistance?
You are having issues with function scope. Your code that called start towards the bottom did not have start in its scope since you defined it inside the click handler. Also, timeout was outside of the scope too, which would cause the interval to go on forever:
$('document').ready(function(){
var timeout,
interval = window.setInterval('$("#start").click()',refreshRate);
function start(){
clearInterval(timeout);
$("#stop").show();
$("#start").hide();
currentPage = table.api().page.info().page + 1;
totalPages = table.api().page.info().pages;
table.api().ajax.reload(function(json){
if (currentPage != totalPages){
table.api().page('next').draw(false);
}
else{
table.api().page('first').draw(false);
}
});
upTime = upTime + (refreshRate / 1000);
clearInterval(interval);
interval = setInterval('$("#start").click()', refreshRate);
}
function timeout(){
timeout = setInterval(function(){
start();
}, 10000);
}
$("#start").click(function(){
start();
});
$("#stop").click(function(){
$("#stop").hide();
$("#start").show();
timeout();
clearInterval(interval);
});
//call start on doc ready to auto start scrolling
start();
});

Animate() doesn't work with scrollTop properly

I'm trying to make a script that scrolls the page automatically to the specific element when I scroll my mouse, but for some reason my animation gets repeated and the scroll goes back and forth.
Edit:
I would like to point out that this doesn't happen if the page scrolls to the last element on the page, but if it scrolls to the second element it will bounce instantly back to the top.
Here's my jQuery:
$(document).ready(function(){
comp = 0;
current_scroll_position = $(window).scrollTop();
console.log("CURRENT SCROLL POSITION = " +current_scroll_position);
second = $("#second").offset().top;
$(window).scroll(function(scroll_action){
$('body').on({
'mousewheel': function(e) {
e.preventDefault();
e.stopPropagation();
}
});
if(comp==0){
console.log("COMP =" +comp);
comp++;
new_scroll_position = $(window).scrollTop();
console.log("YOU SCROLLED, NEW CURRENT POSITION IS :" +new_scroll_position);
if (new_scroll_position > current_scroll_position){ //scroll going down
console.log(new_scroll_position +" > "+ current_scroll_position +" GOING DOWN");
$('body').animate({
scrollTop: second
}, 500,
function(){ //callback function for completed animation
completed_animation_scroll = true;
current_scroll_position = $(window).scrollTop();
console.log(" ANIMATING ");
console.log("CURRENT SCROLL POSITION = " +current_scroll_position);
console.log("NEW SCROLL POSITION = " +new_scroll_position);
console.log("ANIMATION COMPLETED = " +completed_animation_scroll);
console.log(" ******************* ************************ ******************");
$('body').unbind('mousewheel');
comp = 0;
});
}
else{
console.log(new_scroll_position +" > "+ current_scroll_position +" GOING DOWN");
$('body').animate({
scrollTop: 0
}, 500,
function(){ //callback function for completed animation
completed_animation_scroll = true;
current_scroll_position = $(window).scrollTop();
console.log(" ANIMATING ");
console.log("CURRENT SCROLL POSITION = " +current_scroll_position);
console.log("NEW SCROLL POSITION = " +new_scroll_position);
console.log("ANIMATION COMPLETED = " +completed_animation_scroll);
console.log(" ******************* ************************ ******************");
$('body').unbind('mousewheel');
comp = 0;
});
}
}
});
});
Try it:
http://jsfiddle.net/81t6w6zv/2/
The problem is in fact that when scrolling animation is done (including success callback), $(window).scroll handler is triggered and works again (because scrolling animation is actually scrolling and comp becomes equal to 0).
The easiest way to fix it is to wrap comp = 0 in scrolling animation callback function with setTimeout (I changed type of comp variable to bool):
setTimeout
(
function()
{
comp = false;
},
100
);
There are also some "not good things" like binding mousewheel event handler but not unbinding it (if comp not equals to 0), so please take a look at updated fiddle to fix such problems in your code.
And full code:
$(document).ready(function()
{
var comp = false;
var current_scroll_position = $(window).scrollTop();
var secondOffsetTop = $("#second").offset().top;
$(window).scroll(function()
{
if (comp)
{
return;
}
comp = true;
$('body').on('mousewheel', function()
{
return false;
});
var scrollTo = 0;
if ($(window).scrollTop() > current_scroll_position)
{
scrollTo = secondOffsetTop;
}
$('body').animate
(
{
scrollTop: scrollTo
},
500,
function()
{
current_scroll_position = $(window).scrollTop();
$('body').off('mousewheel');
setTimeout
(
function()
{
comp = false;
},
100
);
}
);
});
});

Get static value from variable (scroll function)

I have a "follow scroll" function, but I want it to turn off when it returns to a certain point. My code is as follows:
scrollSidebar: function(scroll) {
var elemPos = $('#bestvideos-2').offset().top,
scroll2 = scroll;
if(scroll2 >= elemPos) {
$('#bestvideos-2').animate({
'margin-top':(scroll - 315)+'px'
},0);
} else {
$('#bestvideos-2').css('margin-top','0');
}
}
$(window).scroll(function() {
var scrollHeight = $(window).scrollTop();
Scroll.scrollSidebar(scrollHeight);
})
The problem is - every time I get up, it goes way up, not following scroll. What I'm thinking is storing a variable elemPos somewhere and keep it static (now it's changing each time I scroll).
What can I do with this?
Pass the value to the scrollSidebar function - make sure that the var elemPos = $('#bestvideos-2').offset().top is executed on dom ready
scrollSidebar: function (elemPos, scroll) {
var scroll2 = scroll;
if (scroll2 >= elemPos) {
$('#bestvideos-2').animate({
'margin-top': (scroll - 315) + 'px'
}, 0);
} else {
$('#bestvideos-2').css('margin-top', '0');
}
}
var elemPos = $('#bestvideos-2').offset().top
$(window).scroll(function () {
var scrollHeight = $(window).scrollTop();
Scroll.scrollSidebar(elemPos, scrollHeight);
})

Categories