This question already has answers here:
How to make JavaScript execute after page load?
(25 answers)
Closed 1 year ago.
I am using following code to execute some statements after page load.
<script type="text/javascript">
window.onload = function () {
newInvite();
document.ag.src="b.jpg";
}
</script>
But this code does not work properly. The function is called even if some images or elements are loading. What I want is to call the function the the page is loaded completely.
this may work for you :
document.addEventListener('DOMContentLoaded', function() {
// your code here
}, false);
or
if your comfort with jquery,
$(document).ready(function(){
// your code
});
$(document).ready() fires on DOMContentLoaded, but this event is not being fired consistently among browsers. This is why jQuery will most probably implement some heavy workarounds to support all the browsers. And this will make it very difficult to "exactly" simulate the behavior using plain Javascript (but not impossible of course).
as Jeffrey Sweeney and J Torres suggested, i think its better to have a setTimeout function, before firing the function like below :
setTimeout(function(){
//your code here
}, 3000);
JavaScript
document.addEventListener('readystatechange', event => {
// When HTML/DOM elements are ready:
if (event.target.readyState === "interactive") { //does same as: ..addEventListener("DOMContentLoaded"..
alert("hi 1");
}
// When window loaded ( external resources are loaded too- `css`,`src`, etc...)
if (event.target.readyState === "complete") {
alert("hi 2");
}
});
same for jQuery:
$(document).ready(function() { //same as: $(function() {
alert("hi 1");
});
$(window).load(function() {
alert("hi 2");
});
NOTE: - Don't use the below markup ( because it overwrites other same-kind declarations ) :
document.onreadystatechange = ...
I'm little bit confuse that what you means by page load completed, "DOM Load" or "Content Load" as well? In a html page load can fire event after two type event.
DOM load: Which ensure the entire DOM tree loaded start to end. But not ensure load the reference content. Suppose you added images by the img tags, so this event ensure that all the img loaded but no the images properly loaded or not. To get this event you should write following way:
document.addEventListener('DOMContentLoaded', function() {
// your code here
}, false);
Or using jQuery:
$(document).ready(function(){
// your code
});
After DOM and Content Load: Which indicate the the DOM and Content load as well. It will ensure not only img tag it will ensure also all images or other relative content loaded. To get this event you should write following way:
window.addEventListener('load', function() {...})
Or using jQuery:
$(window).on('load', function() {
console.log('All assets are loaded')
})
If you can use jQuery, look at load. You could then set your function to run after your element finishes loading.
For example, consider a page with a simple image:
<img src="book.png" alt="Book" id="book" />
The event handler can be bound to the image:
$('#book').load(function() {
// Handler for .load() called.
});
If you need all elements on the current window to load, you can use
$(window).load(function () {
// run code
});
If you cannot use jQuery, the plain Javascript code is essentially the same amount of (if not less) code:
window.onload = function() {
// run code
};
If you wanna call a js function in your html page use onload event. The onload event occurs when the user agent finishes loading a window or all frames within a FRAMESET. This attribute may be used with BODY and FRAMESET elements.
<body onload="callFunction();">
....
</body>
You're best bet as far as I know is to use
window.addEventListener('load', function() {
console.log('All assets loaded')
});
The #1 answer of using the DOMContentLoaded event is a step backwards since the DOM will load before all assets load.
Other answers recommend setTimeout which I would strongly oppose since it is completely subjective to the client's device performance and network connection speed. If someone is on a slow network and/or has a slow cpu, a page could take several to dozens of seconds to load, thus you could not predict how much time setTimeout will need.
As for readystatechange, it fires whenever readyState changes which according to MDN will still be before the load event.
Complete
The state indicates that the load event is about to fire.
This way you can handle the both cases - if the page is already loaded or not:
document.onreadystatechange = function(){
if (document.readyState === "complete") {
myFunction();
}
else {
window.onload = function () {
myFunction();
};
};
}
you can try like this without using jquery
window.addEventListener("load", afterLoaded,false);
function afterLoaded(){
alert("after load")
}
Alternatively you can try below.
$(window).bind("load", function() {
// code here });
This works in all the case. This will trigger only when the entire page is loaded.
window.onload = () => {
// run in onload
setTimeout(() => {
// onload finished.
// and execute some code here like stat performance.
}, 10)
}
If you're already using jQuery, you could try this:
$(window).bind("load", function() {
// code here
});
I can tell you that the best answer I found is to put a "driver" script just after the </body> command. It is the easiest and, probably, more universal than some of the solutions, above.
The plan: On my page is a table. I write the page with the table out to the browser, then sort it with JS. The user can resort it by clicking column headers.
After the table is ended a </tbody> command, and the body is ended, I use the following line to invoke the sorting JS to sort the table by column 3. I got the sorting script off of the web so it is not reproduced here. For at least the next year, you can see this in operation, including the JS, at static29.ILikeTheInternet.com. Click "here" at the bottom of the page. That will bring up another page with the table and scripts. You can see it put up the data then quickly sort it. I need to speed it up a little but the basics are there now.
</tbody></body><script type='text/javascript'>sortNum(3);</script></html>
MakerMikey
I tend to use the following pattern to check for the document to complete loading. The function returns a Promise (if you need to support IE, include the polyfill) that resolves once the document completes loading. It uses setInterval underneath because a similar implementation with setTimeout could result in a very deep stack.
function getDocReadyPromise()
{
function promiseDocReady(resolve)
{
function checkDocReady()
{
if (document.readyState === "complete")
{
clearInterval(intervalDocReady);
resolve();
}
}
var intervalDocReady = setInterval(checkDocReady, 10);
}
return new Promise(promiseDocReady);
}
Of course, if you don't have to support IE:
const getDocReadyPromise = () =>
{
const promiseDocReady = (resolve) =>
{
const checkDocReady = () =>
((document.readyState === "complete") && (clearInterval(intervalDocReady) || resolve()));
let intervalDocReady = setInterval(checkDocReady, 10);
}
return new Promise(promiseDocReady);
}
With that function, you can do the following:
getDocReadyPromise().then(whatIveBeenWaitingToDo);
call a function after complete page load set time out
setTimeout(function() {
var val = $('.GridStyle tr:nth-child(2) td:nth-child(4)').text();
for(var i, j = 0; i = ddl2.options[j]; j++) {
if(i.text == val) {
ddl2.selectedIndex = i.index;
break;
}
}
}, 1000);
Try this jQuery:
$(function() {
// Handler for .ready() called.
});
Put your script after the completion of body tag...it works...
I am trying to interact with a 3rd-party html5 video player in Chrome. I am able to obtain a valid reference to it thusly:
document.getElementsByTagName("video")[1]
...and the readyState is 4, so it's all good.
I can successfully (and with expected result) call:
document.getElementsByTagName("video")[1].play();
document.getElementsByTagName("video")[1].pause();
BUT when I call:
document.getElementsByTagName("video")[1].currentTime = 500;
...the video freezes and it doesn't advance to the new currentTime. The video duration is much longer than 500 seconds, so it should be able to advance to that spot. I have tried other times besides 500, all with same result. If I examine currentTime, it is correct as to what I just set. But it doesn't actually go there. Also I can no longer interact with the video. It ignores any calls to play() or pause() after I try to set currentTime.
Before I call currentTime, when I call play() I get this valid promise back, and everything else still works:
After I call currentTime, when I call play(), I get this broken promise back, and now nothing works on that video object:
If you have a Hulu account you can easily observe this behavior on any video by simply trying it in the Chrome developer console.
EDIT: It was pointed out to me that skipping very much ahead breaks, but skipping a short distance actually works well. Could be related to commercials interspersed.
Try below code, it will first pause then set your position then again play
document.getElementsByTagName("video")[1].pause();
document.getElementsByTagName("video")[1].currentTime = 500;
document.getElementsByTagName("video")[1].play();
Why don't you try this code.
function setTime(tValue) {
// if no video is loaded, this throws an exception
try {
if (tValue == 0) {
video.currentTime = tValue;
}
else {
video.currentTime += tValue;
}
} catch (err) {
// errMessage(err) // show exception
errMessage("Video content might not be loaded");
}
}
Pls. try this:
hv = document.getElementsByTagName("video")[1];
hv.play();
hv.addEventListener('canplay', function() {
this.currentTime = 500;
});
var myVideo=document.getElementsByTagName("video")
if(myVideo[1] != undefind)
{
myVideo[1].currentTime=500;
}
/* or provide id to each video tag and use getElementById('id') */
var myVideo=document.getElementById("videoId")
if(myVideo != undefind)
{
myVideo.currentTime=500;
}
I'm working on an issue for the 2048 game which is a webapp that's been ported to Android:
https://github.com/uberspot/2048-android/issues/15
The JavaScript seems to work everywhere except for a button that toggles a style change in the app. The JavaScript works in a browser, just not in the app. I think it comes down to some code in nightmode.js which begins:
window.onload = function() {
var a = document.getElementById("night");
a.onclick = function() {<<code that toggles day and night colors>>}
Does anyone have a solution to why this JavaScript isn't getting run?
Edit: When on Desktop Chrome and the screen is resized all the way down, the button continues to work. But switching the device mode in Chrome reveals that the thing never works for mobile devices. Since this behavior happens even without the WebView, it looks like just a javascript problem now.
The onload event is fired when everything is loaded. This can take some time.
Plus, window.onload might get overwritten later on...
You can try this instead:
var ready = function ( fn ) {
// Sanity check
if ( typeof fn !== 'function' ) return;
// If document is already loaded, run method
if ( document.readyState === 'complete' ) {
return fn();
}
// Otherwise, wait until document is loaded
// The document has finished loading and the document has been parsed but sub-resources such as images, stylesheets and frames are still loading. The state indicates that the DOMContentLoaded event has been fired.
document.addEventListener( 'interactive', fn, false );
// Alternative: The document and all sub-resources have finished loading. The state indicates that the load event has been fired.
// document.addEventListener( 'complete', fn, false );
};
// Example
ready(function() {
// Do night-mode stuff...
});
see: http://gomakethings.com/a-native-javascript-equivalent-of-jquerys-ready-method/
I was wondering is there possible to pause the video in actually time ?
I tested and video always pause at x.xxx not x.00
video.load();
video.play();
video.ontimeupdate = function(){
if(this.currentTime >= 3) {
video.pause();
}
};
Demo : https://jsfiddle.net/l2aelba/4gh7a058/
Any trick ?
PS: Should be good performance as possible also
I believe you cannot guarantee that the video will stop at an exact moment in time.
According to the documentation for media controller:
Every 15 to 250ms, or whenever the MediaController’s media controller
position changes, whichever happens least often, the user agent must
queue a task to fire a simple event named timeupdate at the
MediaController.
timeupdate event will fire when it can using the least often scenario. It does not give you the option to choose the exact fire times for the updates.
A trick you could do is the following: Remove the timeupdate event, set your own interval and using that check the time.
setInterval(function () {
var ct = video.currentTime;
current_time_el.innerHTML = 'Current time : ' + ct;
if(ct >= 3) {
video.pause();
}
}, 40);
This approach will force you to be more careful with your code though. (e.g clean up your interval with clearInterval() when it is not needed any more)
I have a html5 video event listener that is supposed to wait until the correct time and then pause the video while the user takes part in a quiz. The first 'lesson' works fine, and the second video also appears to add the listener with the correct time to pause. But upon playing the second video it always pauses at 170 seconds, the pause time from the FIRST video.
Also, when I check Chrome's dev panel it actually shows timeCache as having immediately reverted back to the previous videos values as soon as the video is played; unless the video has passed the 170 mark, then it will use the 230 second timeCache value as it should. At first I thought it was because the old event listener was still attached, but I have eliminated that possibility and the problem still persists. Here is the link http://koreanwordgame.com/grammar/
var setPause = function (time) {
var video = $("video").get(0);
var timeCache = time;
video.removeEventListener('timeupdate', timeListener, false);
function timeListener (){
if (video.currentTime >= timeCache && video.currentTime < (timeCache + 0.3)) {
video.pause();
}}
video.addEventListener('timeupdate', timeListener);
};
the first $watch in the directive is triggered each time a new lesson is loaded, it binds the ended event as well as the timeupdate listener via setPause() and then loads and plays the video. The idea is that setPause sets the time that the video will automatically pause at when it reaches, and then the second $watch waits until all the questions have been answered before playing the remainder of the video (generally a congratulations message)
app.directive('videoWatcher', function () {
return function (scope, video, attrs) {
scope.$watch(attrs.videoLoader, function () {
$(video[0]).bind('ended', function () {
$(this).unbind('ended');
if (!this.ended) {
return;
}
scope.tutorialNumber++;
scope.$apply();
scope.loadFromMenu();
});
setPause(scope.currentTutorial.pause);
video[0].load();
video[0].play();
});
scope.$watch(attrs.congrats, function(){
var cT = scope.currentTutorial;
if (scope.questionNumber === cT.material.length){
video[0].play();
setTimeout(function () {
video[0].play();
}, 500);
}
});
};
})
Every time you call your pause function, you create a new instance of the timeListener function. Any reference to timeListener is a reference to the one you just created. So when you're removing the event listener, you're removing the new function, not the one you attached before.
In Javascript, within a given function, it doesn't matter where you declare variables and functions; they are always "hoisted" to the top. So even though you write the timeListener function after your call to removeEventListener, your code behaves as though you declared it at the top of pause. This is why it's usually a good idea to declare all your variables and functions before running any other code (and JSLint will give you a hard time if you don't). The exception is when you explicitly assign a function to a variable.
You can fix this by declaring timeListener outside of pause, so it will always be a reference to the previous instance. Like this:
var timeListener;
function pause(time) {
//timeCache is unnecessary
var video = $("video").get(0),
end = time + 0.3; //cache this so you don't have to add every time
if (timeListener) {
//remove previous timeListener function, if there is one
video.removeEventListener('timeupdate', timeListener, false);
}
//make a new function and save it for later as timeListener
timeListener = function () {
if (video.currentTime >= time && video.currentTime < end) {
video.pause();
}
};
video.addEventListener('timeupdate', timeListener);
};