My website is essentially all one very long page and I've got an element I'd like to click before the page is loaded (it takes a while because it's so long), but I can't get it to trigger.
To test what could possibly be the cause of problems I made a very basic button that wrote to the console when clicked and during the loading phase it did nothing and then eventually once everything was fully loaded it worked.
The strange part is that looking up possible solutions so this problem, people unanimously say that the javascript gets loaded at whatever line it's written in the code and the link to my .js file is the second thing in the (right after ) so surely it should be loading immediately.
This isn't the full code obviously because the site is quite long, but here are the relevant parts:
"use strict";
function test() {
console.log("testingtesting");
}
function init() {
document.getElementById("buttonName").onclick = test;
}
window.onload = init;
<head>
<title>Title</title>
<script src="script.js"></script>
</head>
<body>
<button id="buttonName">
</body>
Does anyone have an explanation for why it's behaving the way it is and if there's anything I can do to change it?
When using an button you could use this method.
"use strict";
function test() {
console.log("testingtesting");
}
<head>
<title>Title</title>
<script src="script.js"></script>
</head>
<body>
<button id="buttonName" onclick="test()"/>
</body>
And if you did like to start the function as soon as its loaded, you could try a self invoking function.
(function () {
// body of the function
}());
The CODE!
$(document).ready(function() {
test();
$("#buttonName").click(function() {
test();
});
function test() {
console.log("testtest");
}
});
button {
height: 80px;
width: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="buttonName">
How it works.
The question you asked is an interesting one.
I've used jquery. A library of javascript that makes most functions alot easier.
First. It doesn't actually matter (to much) where your script sits.
some people place it in the head if its IMPORTANT And reaaaaly needs to be run at the very beginning.
However for the most part you can put javascript before the closing body tag. This is something google, for SEO, approves of.
$(document).ready(function() The function here is called once the page is ready. Or does it? You'll be surprised to know that as a matter of fact its harder for you to stop the script loading before the page is fully loaded. :)
When the browser encounters a script tag when parsing the HTML, it stops parsing and gets to work on the javascript interpreter, which then ends up running the script. The html wont continue until the script execution is complete just incase you have a 'document.ready' function somewhere. This is the default behavior.
As you've written the rest ill assume you already understand what the rest of the code does.
onclick requires a separate function. But as i stated the script will be loaded much before the page is fully loaded. So you can have the onclick work before. However as the button wouldn't have loaded yet there's nothing for you to click.
Another way of approaching the problem.
function test() {
console.log("testingtesting");
}
button {
height: 80px;
width: 80px;
}
<button id="buttonName" onclick="test()"/>
Unlike your script document.getElementById("buttonName").onclick = test; This function is called in the DOM here <button id="buttonName" onclick="test()"/>
thus not requiring another line for the onclick.
Further reading
https://api.jquery.com/
https://www.innoq.com/en/blog/loading-javascript/
http://www.bardev.com/2013/01/03/browser-script-loading/
Related
I've got a script (that also used froogaloop2 https://developer.vimeo.com/player/js-api) that changes the play button on a vimeo vid. It works in JSFiddle but can't get it to work on my actual site. Pressing the play button doesn't do anything, the video doesn't play at all. I've got my scripts organized like so, in the <header> tag. The play/pause script is sitting at the bottom before the <body> tag.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/TweenMax.min.js"></script>
<script type="text/javascript" src="js/remodal.min.js"></script>
<script type="text/javascript" src="js/froogaloop2.min.js"></script>
My full code: https://jsbin.com/fawowaleci/edit?html,css,output
Video script: https://jsfiddle.net/uxhxdcwp/5/
Inside modal: https://jsfiddle.net/qhrmtass/14/
Play/Pause script:
$(function () {
var iframe = document.getElementById('video');
var player = $f(iframe);
player.addEvent('ready', function () {
player.addEvent('finish', onFinish);
});
$('.playpause').click(function () {
player.api('paused', function (paused) {
if (!paused) {
player.api('pause');
$(".playpause").removeClass('pause');
} else {
player.api('play');
$(".playpause").addClass('pause');
}
});
});
function onFinish(id) {
$(".playpause").removeClass('pause');
}
});
Update: it as was suggested but no go. I feel its something with the modal code that's messing it up?
There are two big reasons why you see your code working fine on JSBin versus locally:
If you right click the output element and look at how it's structured, you'll see that all your scripts are getting shifted to run within the opening and closing body tag, contrary to how you wrote the code.
I assume you put together your sample based on looking at the documentation on the Vimeo API page. Note the red box at the very top of the page that indicates that you won't be able to run this locally. Host the below code on a web server and you'll be able to see it execute as you're expecting.
Generally, it's a good idea to put all your tags either within the <head></head> tags or the <body></body> tags. See the discussion in the comments at Is it wrong to place the <script> tag after the </body> tag? for a plethora of information and opinion on that front.
I've put together a working sample (that works on my web server and in JSBin) for you at https://jsbin.com/mojopalode/edit?html,css,output.
Edit: To address your attached picture, it looks as though you're still running this from your desktop. Please see point #2 I made above for why this would continue to fail to work on your end. If you drop this on a webserver (as I tested it on), it should work without a problem.
You should put the scripts, after body tag or initialize variables and listeners on $(document).ready({ });
From looking at your code, only problem I can see is you script runs before actual elements are rendered so its not attaching any listeners to the elements.
I'm new in Javascript and this is my code
<!DOCTYPE html>
<html>
<body>
<img src="http://www.example.com/1/img" border="0" />
<script>
function () {
document.getElementById('test').click();
};
function();
</script>
</body>
</html>
I was trying to open that link when the web page is loaded but I make some errors. Any help?
The way you define and invoke function is not correct. This is invalid syntax construction as function declaration (statement staring with function keyword) requires a name to be valid javascript code.
So you either give function a name an invoke it:
function somename() {
document.getElementById('test').click();
};
somename();
.. or use IIFE (immediately-invoked function expression):
(function() {
document.getElementById('test').click();
})();
However, in your case you don't really need as you don't use it for what it's really useful, i.e. creating new scope. Simple line
document.getElementById('test').click();
would be just enough.
You don't need the example function... remove onclick="example(this)...". Since you are clicking via javascript, the normal function of the click is to go to the link specified in the href attribute anyway.
If you just want to open a new link on page load, you can also remove all the body and just use the following:
<body>
<script>
window.location.assign = "http://example.com";
</script>
</body>
Do it like this:
<!DOCTYPE html>
<html>
<body>
asdf
<script>
document.getElementById('test').onclick();
function yourfunction(){
alert("clicked");
}
</script>
</body>
</html>
What we do here is assigning the function "yourfunction()" to "onclick" of your anchor (the element). Due to the fact that your code is automatically executed when you reload the page (note that we've just posted a line of code into the script tag) you can trigger the onclick event just by using ".onclick()".
However, you're executing "yourfunction()" every time you reload the page and as you click your anchor.
The function itself is pretty boring. It just makes an alert (small window with a message and ok button) which says "clicked".
Further reading:
How can I trigger a JavaScript event click
https://developer.mozilla.org/de/docs/Web/API/GlobalEventHandlers/onclick
https://developer.mozilla.org/de/docs/Web/API/Window/alert
Some further advice. I think you are trying to achieve a "redirection" to another site as soon as you got to a domain. You probably want to do stuff like redirecting a typo ("gogole.com") to your "real" domain (google.com). This shouldn't be done with Javascript! You have to configure your webserver to do so (it's pretty easy). See this for example.
However, ther is also another approach to achieve this:
<meta http-equiv="refresh" content="0; url=http://www.example.com/">
Put this line of code into the of your document.
This question already has answers here:
When does the browser execute Javascript? How does the execution cursor move?
(2 answers)
Closed 9 years ago.
When does the execution of code on tags begin? Is it sequential?
<html>
<head>
<title>Canvas tutorial</title>
<script type="text/javascript">
function draw(){
var canvas = document.getElementById('tutorial');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
}
}
</script>
<style type="text/css">
canvas { border: 1px solid black; }
</style>
</head>
<body onload="draw();">
<canvas id="tutorial" width="150" height="150"></canvas>
</body>
</html>
Above is a working piece of code. Why is script above the canvas element?
There are multiple choices for where to put script functions that will be called later.
In the <head> section. Scripts here will be available immediately and can be used by any other scripts that are executed while the document is being loaded.
In the <body> section mixed in with the HTML. These scripts will be executed at the time that location in the document is parsed. Everything that comes before the script in the DOM will be in place and ready. Everything that comes after the script will not yet be available.
At the very end of the body, right before the </body> tag. At the time these scripts execute, the whole document before it will be ready.
In your particular case, a function is defined in the <head> section so that it is available for execution at some later time. Because of the way the code appears in the <head> section, that code is only a function definition. Nothing actually executes when that code is parsed. The function itself is then executed when the page and its images are done loading via the onload handler specified in this line:
<body onload="draw();">
Only then is the code actually called and run. The draw() function could have been defined in any of the above three locations for this particular issue because the onload handler comes after all three options. As to why the script is above the canvas element, that is just a choice the designer of the page made. They could have located the script after the canvas element if they wanted and the page would have still worked fine.
A good working practice is to place scripts as late in the <body> as possible because that allows the page content to load and display quicker. But, some scripts are needed during the creation of the page (for example scripts that choose to use document.write()) so they must be placed earlier so they are available when needed. Scripts may also be marked defer or async to further delay their loading to allow content to be displayed first.
The preferred method is to put your scripts right below the closing body tag.
However, if it's essential to use a script on a page right away, it's best to keep it in the header.
Because the script merely defines a function that does not get invoked until the page is completely loaded (via the onload body attribute).
Inline elements will execute sequentially, as is the case in your example. However, all your current code does is define a function. It does not execute that function.
In your case you utilized the body onload= event to actually execute the draw() function. This is why you do not have a problem with the code, which seems to be the point of your initial question.
For this reason, it is typically recommended that you not place javascript in the head section unless absolutely necessary, and instead place it as close to closing body tag as possible.
With that said, in this case you define a function, but defining it and executing it are 2 different things. It is not a problem for you to define a function that you do not execute until the DOM is ready, and the DOM element(s) you want to work with are already rendered.
With that said, when you load external javascript files in the head section, it can cause the rendering of the page to block, and depending on the size and number of scripts you're loading that way, it's again advisable to place these at the end of the page. This will avoid the concerns you have in terms of the existence of DOM elements prior to execution of a function that attempts to manipulate those elements.
Do no use an onload attribute on the body element...in fact don't use any attributes on the body element ever.
<head>
<script type="application/javascript">
//<![CDATA[
window.onload = function() {/*load multiple functions here*/}
//]]>
</script>
</head>
Here is the circumstance:
I have 2 pages:
1 x html page
1 x external Javascript
Now in the html page, there will be internal Javascript coding to allow the placement of the window.onload, and other page specific methods/functions.
But, in the external Javascript I want certain things to be done before the window.onload event is triggered. This is to allow customized components to be initialized first.
Is there a way to ensure initialization to occur in the external Javascript before the window.onload event is triggered?
The reason I have asked this, is to attempt to make reusable code (build once - use all over), to which the external script must check that it is in 'order/check' before the Javascript in the main html/jsp/asp/PHP page takes over. And also I am not looking for a solution in jQuery #_#
Here are some of the links on Stack Overflow I have browsed through for a solution:
Javascript - How to detect if document has loaded (IE 7/Firefox 3)
How to check if page has FULLY loaded(scripts and all)?
Execute Javascript When Page Has Fully Loaded
Can someone help or direct me to a solution, your help will be muchness of greatness appreciated.
[updated response - 19 November 2012]
Hi all, thanks for you advice and suggested solutions, they have all been useful in the search and testing for a viable solution.
Though I feel that I am not 100% satisfied with my own results, I know your advice and help has moved me closer to a solution, and may indeed aid others in a similar situation.
Here is what I have come up with:
test_page.html
<html>
<head>
<title></title>
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript" src="test_script_1.js"></script>
<script type="text/javascript" src="test_script_2.js"></script>
<script type="text/javascript">
window.onload = function() {
document.getElementById("div_1").innerHTML = "window.onload complete!";
}
</script>
<style type="text/css">
div {
border:thin solid #000000;
width:500px;
}
</head>
<body>
<div id="div_1"></div>
<br/><br/>
<div id="div_2"></div>
<br/><br/>
<div id="div_3"></div>
</body>
</html>
loader.js
var Loader = {
methods_arr : [],
init_Loader : new function() {
document.onreadystatechange = function(e) {
if (document.readyState == "complete") {
for (var i = 0; i < Loader.methods_arr.length; i++) {
Loader.method_arr[i]();
}
}
}
},
load : function(method) {
Loader.methods_arr.push(method);
}
}
test_script_1.js
Loader.load(function(){initTestScript1();});
function initTestScript1() {
document.getElementById("div_1").innerHTML = "Test Script 1 Initialized!";
}
test_script_2.js
Loader.load(function(){initTestScript2();});
function initTestScript2() {
document.getElementById("div_2").innerHTML = "Test Script 2 Initialized!";
}
This will ensure that scripts are invoked before invocation of the window.onload event handler, but also ensuring that the document is rendered first.
What do you think of this possible solution?
Thanking you all again for the aid and help :D
Basically, you're looking for this:
document.onreadystatechange = function(e)
{
if (document.readyState === 'complete')
{
//dom is ready, window.onload fires later
}
};
window.onload = function(e)
{
//document.readyState will be complete, it's one of the requirements for the window.onload event to be fired
//do stuff for when everything is loaded
};
see MDN for more details.
Do keep in mind that the DOM might be loaded here, but that doesn't mean that the external js file has been loaded, so you might not have access to all the functions/objects that are defined in that script. If you want to check for that, you'll have to use window.onload, to ensure that all external resources have been loaded, too.
So, basically, in your external script, you'll be needing 2 event handlers: one for the readystatechange, which does what you need to be done on DOMready, and a window.onload, which will, by definition, be fired after the document is ready. (this checks if the page is fully loaded).
Just so you know, in IE<9 window.onload causes a memory leak (because the DOM and the JScript engine are two separate entities, the window object never gets unloaded fully, and the listener isn't GC'ed). There is a way to fix this, which I've posted here, it's quite verbose, though, but just so you know...
If you want something to be done right away without waiting for any event then you can just do it in the JavaScript - you don't have to do anything for your code to run right away, just don't do anything that would make your code wait. So it's actually easier than waiting for events.
For example if you have this HTML:
<div id=one></div>
<script src="your-script.js"></script>
<div id=two></div>
then whatever code is in your-script.js will be run after the div with id=one but before the div with id=two is parsed. Just don't register event callbacks but do what you need right away in your JavaScript.
javascript runs from top to bottom. this means.. if you include your external javascript before your internal javascript it would simply run before the internal javascript runs.
It is also possible to use the DOMContentLoaded event of the Window interface.
addEventListener("DOMContentLoaded", function() {
// Your code goes here
});
The above code is actually adding the event listener to the window object, though it's not qualified as window.addEventListener because the window object is also the global scope of JavaScript code in webpages.
DOMContentLoaded happens before load, when images and other parts of the webpage aren't still fully loaded. However, all the elements added to the DOM within the initial call stack are guaranteed to be already added to their parents prior to this event.
You can find the official documentation here.
In the HTML head section:
<script type="text/javascript" src="Scripts/editScripts.js"></script>
Just above the </body> tag(closing tag, bottom of the html page). Also: this is the old code, this is how it was when it was not working:
<script type="text/javascript">if(document.getElementById)initialize();loadEvents();</script>
</body>
</html>
In the editScripts.js file:
/*global document,addFileInput*/
function loadEvents() {
var a = document.getElementById('addField');
a.onclick = addFileInput;
}
var upload_number = 2;
function addFileInput() {
var d = document.createElement("div");
var file = document.createElement("input");
file.setAttribute("type", "file");
file.setAttribute("name", "addFile[]");
file.setAttribute("size", "35");
file.setAttribute("class", "file");
file.setAttribute("id", "addFile"+upload_number);
d.appendChild(file);
document.getElementById("moreUploads").appendChild(d);
upload_number++;
}
This would not work. I replace the javascript in the footer with this.This is the new code, which does work as I expect it to.:
<script type="text/javascript">if (document.getElementById)loadEvents();</script>
And now it does work... I don't see how leaving out that function call, even though it the function it was referring to doesn't exist, would mess things up so royally.
In an unbracketed if statement, only the first statement is conditional. Every statement following it is unconditional regardless of indentation.
Thus, in the first example, loadevents() executed unconditionally.
The browser would have reported an error when attempting to call the "initialize" function since there was no such function. Therefore, the very next line where you call "loadEvents" wouldn't run. See this example:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JS Error Test</title>
</head>
<body>
<script type="text/javascript">
if(document.getElementById) {
initialize();
alert("You shouldn't see me!");
}
</script>
</body>
</html>
In that example, the alert box shouldn't appear because I haven't declared an "initialize" function and the browser will report a JS error. Removing the "initialize" function, however, will cause the alert box to appear.
So that's how by removing the cause of the Javascript error you fixed your problem.
probably because you arent calling your scripts on document load event. so when you called your scripts in the header before your dom fully loaded, none of it worked, but now when you are calling it after the dom loads, it works.
The correct fix for all of this should be calling your scripts after the document fully loads, or at least from the body onload event:
<body onload="initScripts()">
And then add all of the scripts you want to run on page load in the initScripts function.
also, there are much better ways of doing this, for example using jquery, and/or reading this: http://onlinetools.org/articles/unobtrusivejavascript/chapter4.html
You say: "I don't see how leaving out that function call, even though it the function it was referring to doesn't exist, would mess things up so royally." That's inconsistent with the rest of your question, which implies that adding the call messed things up. But I think the text I'm quoting is the correct description.
Here's the real answer. The old code:
if(document.getElementById)loadEvents();
does not call loadEvents if getElementsById is not defined. It's not defined in all browsers.
The new code, instead, you not only leave out the function call: the semantics change as well.
if(document.getElementById)initialize();loadEvents();
always calls loadEvents, so what you want to happen always does.