Scripts execution order - Javascript - javascript

I have a HTML file with several JS scripts :
<!DOCTYPE html> <html>
<head>
<title>Application</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="https://d3js.org/d3.v4.js"></script>
<script src="initMap.js"></script>
<script src="CSVParsing.js"></script>
<script src="nbCinemas.js"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=geometry&callback=initMap"></script>
</head>
<body>
<div id="map" style="width:1000px; height:800px; margin-left:auto; margin-right:auto;"></div>
</body>
My problem is that in my nbCinemas.js file, I am using a global variable that is supposed to have been initialised in CSVParsing.js... but it is not. The thing is, I think that my CSVParsing.js file is loading last. Here is the file:
var arrayData;
d3.csv("cinemas-a-paris.csv", function(data) {
data.forEach(function(d) {
d.lat = +d.lat;
d.lng = +d.lng;
});
arrayData = data;
print();
});
function print() {
console.log("done");
}
In the console, "done" is the last thing written, even though there are other console.logs in my nbCinemas.js file.
Can you help me? Why is my CSVParsing.js file loading last? How can I force it into loading before nbCinemas.js?
Thank you!
Tom.

First, probably
d3.csv("cinemas-a-paris.csv", function(data) {
data.forEach(function(d) {
d.lat = +d.lat;
d.lng = +d.lng;
});
arrayData = data;
print();
});
Is something that is happening in async, so it is send to the event loop, and the "done"message is just show up without that the past function had been finished.
After that, the next file is loaded and initialized and occurs the problem that you have.
One way to deal with this is, verifying that your global variable exists and, if it does, loading dynamicly your next js file like this:
// checking out the variable...
if (typeof variable !== 'undefined') {
// ...the variable is defined, so
var script = document.createElement('script');
script.src = 'http(s)://yourWebSiteURl.com/..js/nbCinemas.js';
}
This way you might ensure that this one last file is loading just after your global variable already exists

Related

How load files added dinamically before call other js file that needs one of that files

First of all, give thanks for reading my question and try to help me and apologize for my English.
I have the following problem...
I'm adding js file and css file dinamically, but sometimes appears an error because load first a static js file before that downlod both files added dinamically.
How can solve that problem?
Until download both files added dynamically, do not load the js file (mapfunctions.js)
My api js file, call a function where add dinamically js file and css file as you can see.
This is my index.html code:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Map Generator</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
// this file add dinamically a js file and a css file
<script src="./js/api/api.js"></script>
// this file needs js file added dinamically, and if is not downloaded crash
<script src="./js/option2/mapfunctions.js"></script>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:50%; height:50%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
customMap.addMap("5b4f12233cfb101f4c2d0537", "map");
});
</script>
</body>
</html>
Error that shows sometimes is:
Error: ReferenceError: mapboxgl is not defined at Object.createMap
This is my api.js file:
let mapboxJsUrl = 'https://api.tiles.mapbox.com/mapbox-gl-js/v0.46.0/mapbox-gl.js';
let mapboxCssUrl = 'https://api.tiles.mapbox.com/mapbox-gl-js/v0.46.0/mapbox-gl.css';
(function(window, document) {
var includeJSFiles = function(url) {
var apiJs = document.getElementsByTagName("script")[0];
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", url);
var css = includeCss(mapboxCssUrl);
if (apiJs !== undefined) {
head.insertBefore(script, apiJs);
} else {
head.insertBefore(script, head.firstChild);
}
head.insertBefore(css, script);
};
var includeCss = function(url) {
var css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", url);
return css;
};
includeJSFiles(mapboxJsUrl);
}(window, document));
In this case, your safest bet may be to use the load event on the window object. According to MDN, load is only fired when all resources and dependencies have loaded so that may make it a better fit for your situation.
I'm not familiar with mapbox, however after a little research I found that the api your trying to use will create a mapboxgl object in your window context.
Seeing as customMap is not defined anywhere, I instead checked for the existence of mapboxgl on window to verify that the Mapbox API was dynamically loading into your sample. I made the following adjustments to your code to achieve dynamically loaded mapbox scripts:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Map Generator</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
// this file add dinamically a js file and a css file
<script src="./js/api/api.js"></script>
// this file needs js file added dinamically, and if is not downloaded crash
<script src="./js/option2/mapfunctions.js"></script>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:50%; height:50%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
/* UPDATE
Add event listener to window object, and register handler on the load event
*/
window.addEventListener('load', function(e) {
customMap.addMap("5b4f12233cfb101f4c2d0537", "map");
});
</script>
</body>
</html>
Also, in your api.js script, you should make the following adjustments to faciliate this:
(function(window, document) {
var includeJSFiles = function(url) {
//var apiJs = document.getElementsByTagName("script")[0];
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", url);
// UPDATE
// Keep this simple, and insert the script as head's first node
head.insertBefore(script, head.firstChild);
var css = includeCss(mapboxCssUrl);
head.insertBefore(css, script);
};
var includeCss = function(url) {
var css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", url);
return css;
};
includeJSFiles(mapboxJsUrl);
}(window, document));
Hope this helps you!

Open a new window after 3 seconds in same tab

Hii this is my second question i will try to explain. This is a code which close the window after 3 seconds i want new window english.html should appear. thanks
<html>
<head>
<script>
function loaded()
{
window.setTimeout(CloseMe, 3000);
}
function CloseMe()
{
window.close();
}
</script>
</head>
<body onLoad="loaded()">
Hello!
</body>
You can't open a new window in response to anything other than a user interaction. "Three seconds after the page has loaded" is not a user interaction so will be blocked by the standard popup blocking rules that all modern browsers are required to implement by the HTML specification.
Try redirecting the user instead, or better yet, don't: Skip the three second page entirely. If something is worth showing to the user, then it is worth showing to the user until they click a link. That way you know they weren't giving their attention to another tab while your content waltzed by unnoticed.
Below is a simple example of how to achieve what you want:
//<![CDATA[
// external.js
var doc, bod, htm, C, E, T; // for use on other loads
addEventListener('load', function(){ // load start
// I threw in a few goodies to study - it will help you later
doc = document; bod = doc.body; htm = doc.documentElement;
C = function(tag){
return doc.createElement(tag);
}
E = function(id){
return doc.getElementById(id);
}
T = function(tag){ // returns an Array of Elements by tag name
return doc.getElementsByTagName(tag);
}
// notice that `window` is implicit, so you don't actually need to use it to access its properties
setTimeout(function(){ // unexecuted functions and Anonymous functions behave the same
location = 'https://www.w3.org'; // it's really this easy to set the `window.location.href`
}, 3000);
});// load end
/* external.css */
html,body{
padding:0; margin:0;
}
.main{
width:980px; margin:0 auto;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<link type='text/css' rel='stylesheet' href='external.css' />
<script type='text/javascript' src='external.js'></script>
</head>
<body>
<div class='main'>
<div>Just a very simple example</div>
</div>
</body>
</html>
Note: You should practice using external sources so they can be cached. Just make sure you change the filename and path to any source you later change.

Change a div background image using javascript if/else

I am trying to get the background image of a div to change at an interval. I created an Array with the images, and every few seconds the function should check the value of "x" against the array length. If X is less, x will increase by one and the background image will change to the next image in the array, otherwise it will set x=0 and restart the process.
The div and initial image shows up how I want, but nothing happens.
I know there are probably better ways to do this, but I am very new to Javascript and want to learn why this code doesn't work. Thanks in advance for the help!!
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ImageChanger</title>
<style type="text/css">
#imagediv {
float:left;
border-style:ridge;
border-width:8px;
border-color:Green;
border-radius:15px;
width:1250px;
height:450px;
background-image:url(images/landscape1.jpg)
}
</style>
<script type="text/javascript">
function displayNextImage() {
var x;
If (x<imageArray.length) {
x=x+1;
document.getElementById("imagediv").style.backgroundImage=images[x];
}
else {
x=0;
document.getElementById("imagediv").style.backgroundImage=images[x];
}
function startTimer() {
setInterval(displayNextImage, 3000);
}
var imageArray=new Array();
images[0] = "images/landscape1.jpg";
images[1] = "images/landscape2.jpg";
images[2] = "images/landscape3.jpg";
images[3] = "images/landscape4.jpg";
</script>
</head>
<body>
<div id="imagediv">
</div>
</body>
</html>
If (x<imageArray.length) {..
should be
if (x<imageArray.length) {
Javascript is case-sensitive.
Also you have some missing braces like you are not closing
function displayNextImage() { ....
Use your browser console to debug. These syntax errors will be shown there.
As far as syntax issues go:
As #Zee stated, If should be lowercase (if)
Also, as #Zee and some others stated, you are not closing function displayNextImage() { with a closing brace }.
You are improperly defining the background-image property in your function, whereas you defined it correctly in the block of CSS. You must wrap the image name with url().
You are never calling your timeout function, startTimer.
You create a new array imageArray but then use an undeclared array images

javascript code in html to js file

I am struggling with the following problem.
I have made a memorygame with javascrpt for school.It all works fine, but my teacher told me that i can not have on line of javascript in my HTML, like this :
HTML :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="styles.css">
<title>Memory spelen</title>
</head>
<body>
<script type="text/javascript" src="javascript.js"></script>
<div id="memory_board"></div>
<script>newBoard();</script>
</body>
</html>
The newBoard() is applied to the memory_board div. How can i take this little piece of script out of my HTML file and place it in my js file, to still function properly.
Thanks in advance
Inside of your javascript.js put this
window.onload = function {
// content of your script
var newBoard = function(){
// the new updated newBoard() function from below
}
// other parts of your script
if(window.location.href == 'your-url') {
// now, after the newBoard() has been updated
// the next to lines are not needed
// var board = document.getElementById('memory_board');
// board.innerHTML = newBoard();
// just call the function
newBoard();
}
};
UPDATE
I just took a look at your old fiddle and I changed your newBoard function to this
function newBoard(){
tiles_flipped = 0;
var output = '';
memory_array.memory_tile_shuffle();
for(var i = 0; i < memory_array.length; i++){
var div = document.createElement('DIV');
div.id = "tile_" + i;
(function(div,i){
div.onclick = function() {
memoryFlipTile(this, memory_array[i]);
};
}(div,i));
document.getElementById('memory_board').appendChild(div);
}
}
Check the working fiddle.
try to put it like this in external js file
$(document).ready(function(){
newBoard();
});
It looks that you need to call newBoard() method on onload event of memory_board div , You can do this in following ways:
<div id="memory_board" onload="javascript:newBoard()" ></div> // use onload event of memory_board
you can use onload function on the javascript. It will call the function when all the HTML tag is loaded on the screen.

"getElementsByTagName(...)[0]" is undefined?

I have the following code, which basically toggles through a bunch of images.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var num = 1;
img = document.getElementsByTagName("img")[0];
hbutton = document.getElementsByTagName("h1")[0];
hbutton.onclick = function() {
num += 1;
img.src = num + ".jpg";
}
</script>
</head>
<body>
<h1>Press Here!</h1>
<img src = "1.jpg"></img>
</body>
</html>
For some reason, when I run it, nothing happens, because of the following error as displayed by my Firebug console.
hbutton is undefined
---
hbutton.onclick = function() {
When I run just the JS after the page has loaded however, it works perfectly fine!!! Why is this?
Your code is executing before the h1 tag is defined. You must run it in an onload handler or put it just before /body
JavaScript is interpreted top-to-bottom. So at the place where your <script> executes, no h1 tags are known yet.
Try putting the <script>-Tag to the bottom of your page. Otherwise, if you need the script at the beginning of the page, an onLoad-Handler might help:
<script type="text/javascript">
function onLoadHandler() {
// your original javascript code here...
}
</script>
<body onload="onloadHandler()">
<!-- HTML Code here-->
When you put it in the header, your h1 is not loaded yet. hbutton becomes undefined, not an object. Then when you try to set .onclick, it breaks because you cant set properties of something undefined. When you put the code in the body, your h1 is already loaded, so the code works as you expected it to.
You can fix this by leaving your code at the top, but only calling it after an onload event.
The head gets executed before the dom is loaded. Put it on the button of the page or put an onload function in the body tag.
It cannot find document.getElementsByTagName("img") when the Document isnt ready yet, because it is simply not there yet.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function onDocumentReady(){
var num = 1;
img = document.getElementsByTagName("img")[0];
hbutton = document.getElementsByTagName("h1")[0];
hbutton.onclick = function() {
num += 1;
img.src = num + ".jpg";
}
}
</script>
</head>
<body onload="onDocumentReady()">
<h1>Press Here!</h1>
<img src = "1.jpg"></img>
</body>
</html>
or simply do this:
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1>Press Here!</h1>
<img src = "1.jpg"></img>
<script type="text/javascript">
var num = 1;
img = document.getElementsByTagName("img")[0];
hbutton = document.getElementsByTagName("h1")[0];
hbutton.onclick = function() {
num += 1;
img.src = num + ".jpg";
}
</script>
</body>
</html>
The problem is that the script is being executed immediately it is encountered during page load.
Since it's at the top of the page, in the header, this means that it is executed before the page has loaded the <h1> element (or any of the rest of the body).
Therefore, when it asks for getElementsByTagName('h1'), there aren't any matching elements at that moment in time.
You need to either:
* move the code to the end of the script.
* or wrap it in a function, and trigger the function to execute when the page has finished loading -- ie use the onload method.

Categories