Execute Js code until the document is ready - javascript

What's the best way to keep executing a JS code (each 100 ms in m case) until the document is ready.
setInterval(function() {
xajax_updateLoader();
}, 100);
One the document is ready. The execution should stop.

var updateInterval;
$(function(){
updateInterval= setInterval(function() {
xajax_updateLoader();
}, 100);
});
$(windows).load(function(){
clearInterval(updateInterval)
});

var interval = setInterval(function() { ... }, 100);
window.onload = function() { clearInterval(interval); }
This clears the interval on the onload event.

var handle = setInterval(function() {
xajax_updateLoader();
if (jQuery.isReady) {
//DOM is ready
clearInterval(handle);
}
}, 100);

Like this
domReady = false;
var ctx = setInterval(function() {
if (domReady === true)
{
clearInterval(ctx);
}
// your code here
}, 100);
if (typeof document.addEventListener !== 'undefined') // chrome / safari / firefox
{
document.addEventListener("DOMContentLoaded", function(){
domReady = true;
document.removeEventListener('DOMContentLoaded');
}, false);
}
else if (typeof document.attachEvent !== 'undefined') // IE
{
document.attachEvent("onreadystatechange", function(){
if ( document.readyState === "complete" )
{
document.detachEvent( "onreadystatechange", arguments.callee );
domReady = true;
}
});
}

Use clearInterval()
var interval = setInterval(function() { ... }, 100);
$(document).ready(function(){
clearInterval(interval);
});

Related

check if the page is on the top of the window

I need to check if an html page is on the top of the window or not.
So, i am using this code:
$(window).scroll(function(){
a = ($(window).scrollTop());
if (a>0) {
alert('page not in top');
}
});
But this is not working as expected because the event should be fired only when the user stops the scroll action. Any idea?
Try this:
var timer = null;
$(window).addEventListener('scroll', function() {
if(timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(function() {
// do something
}, 150);
}, false);
Or this one:
var timer;
$(window).bind('scroll',function () {
clearTimeout(timer);
timer = setTimeout( refresh , 150 );
});
var refresh = function () {
// do stuff
console.log('Stopped Scrolling');
};
Use setTimeout:
var timeout;
$(window).scroll(function() {
clearTimeout(timeout);
timeout = setTimeout(function(){
a = $(window).scrollTop();
if ( a > 0 ) {
alert('page not in top');
}
}, 100);
});

How would I toggle the state of a setInterval function in jQuery?

I want to be able to click a an element with an id of pause to start a count of the elements in a time object and if I re click the pause it will stop it and reclick start it exactly like the toggle feature in JQuery but with a setInteval function how would I go about doing this?
$("#pause").click(function(ffe) {
if(on == true) {
on = false
alert("on");
}
else {
on = true;
alert("off");
}
if(on == false) {
setInterval(function() {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}, 100);
}
else {
alert("Error");
}
});
A classic technique is to use a single master setInterval loop and simply use if..else logic to determine what needs to run. This is how a lot of javascript games work:
var on = true;
// Our master scheduler:
setInterval(function() {
if (on) {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}
}, 100);
// Code to handle the pause button
$("#pause").click(function(ffe) {
on = !on;
}
You can use the setTimeout function, if you want to run the function once, setInterval runs continuously, try the following:
var on = false;
$("#pause").click(function(ffe) {
if (on) {
on = false;
setTimeout(function() {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}, 100);
} else {
on = true;
}
});
You need to use .clearInterval() to stop the execution.
Here is the code: (THE WORKING DEMO)
$("#pause").click((function () {
var interId = null;
var $ul = $("#timet ul");
return function (e) {
if (interId) {
$(this).text("start");
clearInterval(interId);
interId = null;
} else {
$(this).text("pause");
interId = setInterval(function () {
$ul.append($('<li>').text($('li', $ul).length));
}, 100);
}
};
}()));​

How to activate setInterval() incase a text control has the focus

Actually I have an update enquery into this point .
I have smth like that :
$(document).ready(function() {
setInterval(doSmth, 10000);
function doSmth() {
var result = document.getElementById("fooText").value;
if (result != "") {
doSmthElse(result);
}
});
}
}
});
I need to activate the interval ,that is fired each 10 seconds, in case only a text control has the focus else do nothing !!
Code for you is:
$(document).ready(function() {
setInterval(function(){
var result = $("#fooText").val();
if (result != "") {
// if
} else {
// else
}
}, 10000);
You can set the interval on focus of the field, and clear it on blur:
var interval;
$(field).focus(function() {
interval = setInterval(doMsth, 10000);
});
$(field).blur(function() {
clearInterval(interval);
});
(the interval var has to be global)
You can implement this in 2 ways,
Let the timer run and inside the function check if the activeElement == <text input>, then execute the rest of the function else return.
$(document).ready(function() {
setInterval(doSmth, 5000);
function doSmth() {
var resultEl = document.getElementById("fooText");
if (document.activeElement.id != resultEl.id) { return false; }
if (resultEl.value != "") {
doSmthElse(resultEl.value);
}
}
function doSmthElse(result) { alert(result);}
});
DEMO here
Set the timer on focus of the text box and remove the timer onblur of the input box.
$('#fooText').focus ( function () {
timer = setInterval(function() {
var textVal = $('#fooText').val();
if (textVal != '') {
doSmthElse(textVal );
}
}, 5000);
});
$('#fooText').blur (function () {
if (timer != '') clearInterval(timer);
});
DEMO here

How do I know when I've stopped scrolling?

How do I know when I've stopped scrolling using Javascript?
You can add an event handler for the scroll event and start a timeout. Something like:
var timer = null;
window.addEventListener('scroll', function() {
if(timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(function() {
// do something
}, 150);
}, false);
This will start a timeout and wait 150ms. If a new scroll event occurred in the meantime, the timer is aborted and a new one is created. If not, the function will be executed. You probably have to adjust the timing.
Also note that IE uses a different way to attach event listeners, this should give a good introduction: quirksmode - Advanced event registration models
There isn't a "Stopped Scrolling" event. If you want to do something after the user has finished scrolling, you can set a timer in the "OnScroll" event. If you get another "OnScroll" event fired then reset the timer. When the timer finally does fire, then you can assume the scrolling has stopped. I would think 500 milliseconds would be a good duration to start with.
Here's some sample code that works in IE and Chrome:
<html>
<body onscroll="bodyScroll();">
<script language="javascript">
var scrollTimer = -1;
function bodyScroll() {
document.body.style.backgroundColor = "white";
if (scrollTimer != -1)
clearTimeout(scrollTimer);
scrollTimer = window.setTimeout("scrollFinished()", 500);
}
function scrollFinished() {
document.body.style.backgroundColor = "red";
}
</script>
<div style="height:2000px;">
Scroll the page down. The page will turn red when the scrolling has finished.
</div>
</body>
</html>
Here's a more modern, Promise-based solution I found on a repo called scroll-into-view-if-needed
Instead of using addEventListener on the scroll event it uses requestAnimationFrame to watch for frames with no movement and resolves when there have been 20 frames without movement.
function waitForScrollEnd () {
let last_changed_frame = 0
let last_x = window.scrollX
let last_y = window.scrollY
return new Promise( resolve => {
function tick(frames) {
// We requestAnimationFrame either for 500 frames or until 20 frames with
// no change have been observed.
if (frames >= 500 || frames - last_changed_frame > 20) {
resolve()
} else {
if (window.scrollX != last_x || window.scrollY != last_y) {
last_changed_frame = frames
last_x = window.scrollX
last_y = window.scrollY
}
requestAnimationFrame(tick.bind(null, frames + 1))
}
}
tick(0)
})
}
With async/await and then
await waitForScrollEnd()
waitForScrollEnd().then(() => { /* Do things */ })
(function( $ ) {
$(function() {
var $output = $( "#output" ),
scrolling = "<span id='scrolling'>Scrolling</span>",
stopped = "<span id='stopped'>Stopped</span>";
$( window ).scroll(function() {
$output.html( scrolling );
clearTimeout( $.data( this, "scrollCheck" ) );
$.data( this, "scrollCheck", setTimeout(function() {
$output.html( stopped );
}, 250) );
});
});
})( jQuery );
=======>>>>
Working Example here
I did something like this:
var scrollEvents = (function(document, $){
var d = {
scrolling: false,
scrollDirection : 'none',
scrollTop: 0,
eventRegister: {
scroll: [],
scrollToTop: [],
scrollToBottom: [],
scrollStarted: [],
scrollStopped: [],
scrollToTopStarted: [],
scrollToBottomStarted: []
},
getScrollTop: function(){
return d.scrollTop;
},
setScrollTop: function(y){
d.scrollTop = y;
},
isScrolling: function(){
return d.scrolling;
},
setScrolling: function(bool){
var oldVal = d.isScrolling();
d.scrolling = bool;
if(bool){
d.executeCallbacks('scroll');
if(oldVal !== bool){
d.executeCallbacks('scrollStarted');
}
}else{
d.executeCallbacks('scrollStopped');
}
},
getScrollDirection : function(){
return d.scrollDirection;
},
setScrollDirection : function(direction){
var oldDirection = d.getScrollDirection();
d.scrollDirection = direction;
if(direction === 'UP'){
d.executeCallbacks('scrollToTop');
if(direction !== oldDirection){
d.executeCallbacks('scrollToTopStarted');
}
}else if(direction === 'DOWN'){
d.executeCallbacks('scrollToBottom');
if(direction !== oldDirection){
d.executeCallbacks('scrollToBottomStarted');
}
}
},
init : function(){
d.setScrollTop($(document).scrollTop());
var timer = null;
$(window).scroll(function(){
d.setScrolling(true);
var x = d.getScrollTop();
setTimeout(function(){
var y = $(document).scrollTop();
d.setScrollTop(y);
if(x > y){
d.setScrollDirection('UP');
}else{
d.setScrollDirection('DOWN');
}
}, 100);
if(timer !== 'undefined' && timer !== null){
clearTimeout(timer);
}
timer = setTimeout(function(){
d.setScrolling(false);
d.setScrollDirection('NONE');
}, 200);
});
},
registerEvents : function(eventName, callback){
if(typeof eventName !== 'undefined' && typeof callback === 'function' && typeof d.eventRegister[eventName] !== 'undefined'){
d.eventRegister[eventName].push(callback);
}
},
executeCallbacks: function(eventName){
var callabacks = d.eventRegister[eventName];
for(var k in callabacks){
if(callabacks.hasOwnProperty(k)){
callabacks[k](d.getScrollTop());
}
}
}
};
return d;
})(document, $);
the code is available here: documentScrollEvents
Minor update in your answer. Use mouseover and out function.
$(document).ready(function() {
function ticker() {
$('#ticker li:first').slideUp(function() {
$(this).appendTo($('#ticker')).slideDown();
});
}
var ticke= setInterval(function(){
ticker();
}, 3000);
$('#ticker li').mouseover(function() {
clearInterval(ticke);
}).mouseout(function() {
ticke= setInterval(function(){ ticker(); }, 3000);
});
});
DEMO
I was trying too add a display:block property for social icons that was previously hidden on scroll event and then again hide after 2seconds. But
I too had a same problem as my code for timeout after first scroll would start automatically and did not had reset timeout idea. As it didn't had proper reset function.But after I saw David's idea on this question I was able to reset timeout even if someone again scrolled before actually completing previous timeout.
problem code shown below before solving
$(window).scroll(function(){
setTimeout(function(){
$('.fixed-class').slideUp('slow');
},2000);
});
edited and working code with reset timer if next scroll occurs before 2s
var timer=null;
$(window).scroll(function(){
$('.fixed-class').css("display", "block");
if(timer !== null) {
clearTimeout(timer);
}
timer=setTimeout(function(){
$('.fixed-class').slideUp('slow');
},2000);
});
My working code will trigger a hidden division of class named 'fixed-class' to show in block on every scroll. From start of latest scroll the timer will count 2 sec and then again change the display from block to hidden.
For more precision you can also check the scroll position:
function onScrollEndOnce(callback, target = null) {
let timeout
let targetTop
const startPosition = Math.ceil(document.documentElement.scrollTop)
if (target) {
targetTop = Math.ceil(target.getBoundingClientRect().top + document.documentElement.scrollTop)
}
function finish(removeEventListener = true) {
if (removeEventListener) {
window.removeEventListener('scroll', onScroll)
}
callback()
}
function isScrollReached() {
const currentPosition = Math.ceil(document.documentElement.scrollTop)
if (targetTop == null) {
return false
} else if (targetTop >= startPosition) {
return currentPosition >= targetTop
} else {
return currentPosition <= targetTop
}
}
function onScroll() {
if (timeout) {
clearTimeout(timeout)
}
if (isScrollReached()) {
finish()
} else {
timeout = setTimeout(finish, 500)
}
}
if (isScrollReached()) {
finish(false)
} else {
window.addEventListener('scroll', onScroll)
}
}
Usage example:
const target = document.querySelector('#some-element')
onScrollEndOnce(() => console.log('scroll end'), target)
window.scrollTo({
top: Math.ceil(target.getBoundingClientRect().top + document.documentElement.scrollTop),
behavior: 'smooth',
})
Here's an answer that doesn't use any sort of timer, thus in my case predicted when the scrolling actually ended, and is not just paused for a bit.
function detectScrollEnd(element, onEndHandler) {
let scrolling = false;
element.addEventListener('mouseup', detect);
element.addEventListener('scroll', detect);
function detect(e) {
if (e.type === 'scroll') {
scrolling = true;
} else {
if (scrolling) {
scrolling = false;
onEndHandler?.();
}
}
}
}

clearInterval(); then call interval again

I have a setInterval function
var auto_refresh = setInterval(function () {
if ($('#addNewJuicebox:visible')) {
clearInterval();
}
//rest of function
}, 8000); // refresh every 5000 milliseconds
I want to call the setInterval later again, what's the best way to do that?
Try breaking your code up into the storage of the interval and the setting.
var auto_refresh = "";
function startRefresh() {
if (auto_refresh != "") {
// already set
return;
}
auto_refresh = setInterval(function() {
if ($('#addNewJuicebox:visible')) {
clearInterval(auto_refresh);
auto_refresh = "";
}
}, 8000);
}
Added a jsfiddle example for demonstrating starting and stopping an interval
http://jsfiddle.net/Jf8PT/
This may be what you're looking for
Function TaskRunner(run, interval) {
this._taskId = null;
this._run = run;
this._interval = interval
}
TaskRunner.prototype.start = function(){
if (this._taskId) {
return; // Already running
}
this._taskId = setInterval(this._taskId, this._interval);
}
TaskRunner.prototype.stop = function(){
if (!this._taskId) {
return; // Not running
}
clearInterval(this._taskId);
this._taskId = null;
}
var task = new TaskRunner(
function(){
if ($('#addNewJuicebox:visible')) {
task.stop();
}
// Do the update
}, 5000);
Now you can call `task.start()` from anywhere in your code to restart it.
clearInterval takes in a reference to the timer that you want to clear, you need to pass that in to it:
var auto_refresh = null;
var refresh = function () {
if ($('#addNewJuicebox').is(':visible')) {
clearInterval(auto_refresh);
auto_refresh = null;
}
};
var start_refreshing = function() {
if(auto_refresh != null) return;
auto_refresh = setInterval(refresh, 8000);
};
start_refreshing();
Maybe you just want to use setTimeout() instead, so that you have the control you're looking for?

Categories

Resources