Differences in script execution order using Chrome vs Firefox - javascript

Because I am new to programming and trying to learn several languages at once, I made a series of files in one folder in order to test how these different languages/technologies work together. In the folder I have two php files (including the main file I am testing; 'index.php'), a css file, a json file and two javascript files. The problem is that when I run it in the browser using a XAMPP apache server, the scripts that refer to the files 'script.js' and 'secondscript.js' on the 'index.php' file seem to be executing in the wrong order depending on the situation. I expected them to both be executed in the order in which they appeared on the file but if I use Chrome, 'secondscript.js' is always executed first even if I swap the order that they are written in the file and if I use Firefox, 'script.js' is always executed first. Here is the code:
index.php:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css"> <!-- ADD CSS -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- ADD JQUERY -->
<script> window.jQuery || document.write('<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"><\/script>')</script> <!-- ADD JQUERY BACKUP -->
<script src="secondscript.js"></script>
<!-- ADD JQUERY TEST -->
<script src="script.js"></script>
<!-- ADD JAVASCRIPT -->
</head>
<body>
<div id="ajaxdiv"></div>
<!-- ADD AJAX TEST -->
<?php include 'server.php'?>
<!-- ADD PHP -->
<noscript>Sorry, your browser does not support JavaScript!</noscript>
<!-- ADD BACKUP FOR JSLESS BROWSER -->
</body>
</html>
script.js:
document.write("<h1>Header</h1>")
Request = new XMLHttpRequest()
Request.open('GET', 'json.json')
Request.onload = function (){
Data = JSON.parse(Request.responseText)
p = document.createElement('p')
node = document.createTextNode(Data[1].Three)
p.appendChild(node)
document.getElementById("ajaxdiv").appendChild(p)
}
Request.send()
secondscript.js:
$(function() { alert('Alert') })
server.php:
<?php echo 'PHP TEST'?>
style.css:
body {background-color: pink}
h1 {color: red}
p {color: purple}
json.json:
[{"One": "A", "Two": "B"}, {"Three": "C", "Four": "D"}]
edit: by 'execute first' I mean it seems that way to me because the 'C' that appears via ajax appears before or after the alert message depending on the browser.

Related

Javascript executing incorrectly on Apache Cordova index.js/.html

So in an application I'm writing using Apache Cordova within Visual Studio, I am attempting to add functionality to the default index.html and index.js. However, my code within my index.js is executing very oddly - the debugger in VS shows that the $('#favorite-lot') is executed, but nothing within the .click(function()) method is. Is there any reason why this would be so?
Index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/JQueryMobile/jquery.mobile-1.4.5.min.css" />
<link rel="stylesheet" type="text/css" href="css/index.css">
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="scripts/platformOverrides.js"></script>
<script src="scripts/JQueryMobile/jquery.mobile-1.4.5.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
</head>
<body>
<div role="main" class="ui-content">
<a id="favorite-lot" href=""><h5>Favorite Lot</h5></a>
</div>
</body>
</html>
Index.js
//This method is called on page load to set the favorite lot on the index page
//the document bit is called, but the if statement within it & ready aren't
//$(document).ready(function () {
$('#favorite-lot').click(function () {
var storage = window.localStorage;
var href = storage.getItem("favoriteLot");
//now redirect
window.location.replace(href);
});
//});
Note I have tried enclosing my function within a document.ready (see commented out code), however the results are the same.
EDIT: So I figured this issue out, and it was a fairly simple error: I wasn't including the jQuery code itself, just jQuery.mobile, and additionally, the jQuery has to load before jQuery.mobile for the .mobile stuff to work. Side note, I also didn't realize .mobile enables Ajax on most links/redirections, and had to disable that for some of my other code; maybe if you've found this post, you're suffering from the other problem as well

javascript not working from network drive

I'm trying to run the below file. It runs perfectly fine when I run it on a local drive but if I place it on a network drive it no longer works. Any idea why this might be?
The below is code that I am trying to run. It is using pivottable from here: https://github.com/nicolaskruchten/pivottable.
<!DOCTYPE html>
<html>
<head>
<title> Demo</title>
<!-- external libs from cdnjs -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<!-- PivotTable.js libs from ../dist -->
<link rel="stylesheet" type="text/css" href="../dist/pivot.css">
<script type="text/javascript" src="../dist/pivot.js"></script>
<style>
body {font-family: Verdana;}
</style>
<!-- optional: mobile support with jqueryui-touch-punch -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
</head>
<body>
<script type="text/javascript">
// This example shows custom aggregators using
$(function(){
var tpl = $.pivotUtilities.aggregatorTemplates;
$.getJSON("col.json", function(frontier) {
$("#output").pivotUI(frontier, {
rows: ["Manager"], cols: ["Sector"],
aggregators: {
"Number of Positions": function() { return tpl.count()() },
"Manager Weight": function() { return tpl.sum()(["Port"])},
"Benchmark XGCC Weight": function() { return tpl.sum()(["Bench"])},
}
});
});
});
</script>
<div id="output" style="margin: 30px;"></div>
</body>
</html>
File:/// urls will run in a different context than HTTP/HTTPS and other contexts (internal, public, private, unsafe). What limitations in question depend on the specific browser, the OS and the context itself.
If you must execute JavaScript within HTML, the safest and most assured way to run is to have it running via a web server.
Also worth noting, there are a few local/relative files. ../dist/pivot.js and ../dist/pivot.css are you sure you're saving those files, and they are in the correct relative path as well?

Avoid Render Blocking by plugins which have both css and js dependencies

I am using a jQuery plugin it has plugin.css and plugin.js as dependencies and code is in script.js. I cant have plugin.js and script.js merged because i am using plugin only on one webpage of my website.
In order to make sure plugin.css is loaded before execution of plugin.js and script.js, normally I have no option but to have plugin.css in <head> which causes render blocking(until all resources in head are loaded,
browser doesnt render html).
Normal Way: Having CSS in <head> and JS before </body>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/plugin.css">
</head>
<body>
// content goes here
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>
<script src="/js/plugin.js"></script>
<script src="/js/script.js"></script>
</body>
</html>
Proposed Way: Load CSS and JS via ajax calls and inject them when all of them are loaded, using jQuery $.when promise
<!DOCTYPE html>
<html>
<head>
</head>
<body>
// content goes here
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>
<script class="load-plugin">
$(document).ready(function(){
var loadPlugin = {
css : $.ajax({ url: $(".jquery-plugin-css").data("src") }),
js : $.ajax({ url: $(".jquery-plugin-js").data("src")}),
};
var scriptJs = $.ajax({ url: $(".script-js").data("src") });
$.when(loadPlugin.css, loadPlugin.js, scriptJs).then(function(){
loadPlugin.css.done(function(data){
$(".jquery-plugin-css").html(data);
});
loadPlugin.js.done(function(data){
$(".jquery-plugin-js").html(data);
});
scriptJs.done(function(data){
$(".script-js").html(data);
});
});
});
</script>
<style class="jquery-plugin-css" data-src="/css/plugin.css"></style>
<script class="jquery-plugin-js" data-src="/js/plugin.js"></script>
<script class="script-js" data-src="/js/script.js"></script>
</body>
</html>
This improved my first render time from 3.4 secs to 2.4 secs and total page load time from 8.5secs to 8secs.
But this has some limitations:
Publicly hosted urls cant be used because the urls inside the plugin files like background-images inside css files if mentioned relative to their directory then the path changes after code is pasted into html.
As the injected code is not part of the source files or external scripts they cant be debugged in developer tools.
This way of lazyloading plugins has pros and equal amount of cons. Can anyone suggest is it worth it to do it this way or any better way to do things.
What I would try is:
Combine the JS files so that the dependent code is after plugin.js
Insert a script at the bottom of the page to dynamically load the CSS first and the combined JS second. If you need example code, you might look at https://github.com/filamentgroup/loadJS/ and https://github.com/filamentgroup/loadCSS/.
Using this approach, neither the CSS nor the JS blocks rendering. The CSS is appended to the DOM, so there should be no problems with relative URLs.

Firefox Addon Scripting Trusted Page Content

So I'm trying to use a chrome:// URI in my add-on and I want to use a page-worker on it using the scripting trusted content method, however it seems to not work when I hard code the URI in, the chrome://<package name>/<part>/<file>; however, it works when I use the self.data.url('filename'). I want to use the chrome:// URI is because I use a GUID instead of the email style as the add-on's ID and also I don't want to use the resource:// URI.
Content Script
addon.port.emit('hi');
HTML
<html>
<head>
<meta charset="UTF-8">
<title>Gaia Utils Settings</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/dropdown.min.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/settings.dev.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/test.dev.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="css/settings.css" rel="stylesheet" type="text/css">
<link href="css/poststyle.css" rel="stylesheet" type="text/css">
</head>
<body>
<nav id="navbar_header" class="navbar navbar-blue navbar-static-top"></nav>
<div id="content_wrapper" class="container">
<div id="content_padding" class="container"></div>
</div>
<footer class="footer"></footer>
</body>
</html>
main.js
var PageWorker = require("sdk/page-worker");
PageWorker.Page({
contentURL: "chrome://gaiautils/content/settings.dev.html",
onMessage: function(message) {
console.log(message);
}
});
I know I can use a page-mod and attach the scripts to it with that, but I'd rather call the scripts from within the file and be able to communicate with the main add-on code. So is there a way so that I can have my cake and eat it too - using the hard coded chrome:// URI in conjunction with calling the scripts from within the HTML file while being able to have those scripts communicate back to the main.js file?
How can I have it so that I can use the addon.port.emit() in the content scripts that are called directly in the HTML file so that I don't have to use the self.data.url('htmlFile'), because I don't want to use the resource://pageckage-GUID-at-jetpack/path/to/file
The SDK only considers pages "trusted" if the URL you're loading is part of the add-on assets (data/). chrome:// URIs are not. Hence you'll need to use regular content scripts via the contentScriptFile: [...] option in your PageWorker definition.
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
Don't ever load remote scripts for security reasons (and performance reasons to a far lesser extent)! Ship a local copy of jQuery if you want to use it.

Calling a function from one JavaScript file which requires another

I am trying to call a function written in one JavaScript file from another JavaScript file. I have the following code, but it doesn't work:
My HTML file
<script type="text/javascript" src="js1.js"></script>
<script type="text/javascript" src="js2.js"></script>
<script language="javascript">
js1();
</script>
js1.js
function js1()
{
alert("Hello from js1");
js2();
}
js2.js
function js2()
{
alert("Hello from js2");
}
What can I do?
Try changing the order
<script type="text/javascript" src="js2.js"></script>
<script type="text/javascript" src="js1.js"></script>
<script language="javascript">
js1();
</script>
Because you call js2(); inside js1.js, so the script js2.js should be executed before.
In your case, i think it should still work without changing orders like this because you call js2(); inside a function. When this script is executed:
function js1()
{
alert("Hello from js1");
js2();
}
Even the js2.js is not executed yet, but you do not actually call js2(); at this time.
Just try it to see if it works.
I'm going to assume that's your entire HTML page.
In order to have those scripts run, you need to have those JavaScript files in the same folder as your webpage, and to actually have a proper HTML page!
In your HTML page, you need to include the references to your js1 and js2 files in either the head or body, and include the script you've written in the HTML page itself in the body so that it'll execute when it's loaded:
<!DOCTYPE html>
<!-- ^ Declaring this DOCTYPE means this is a HTML5 page. -->
<html>
<head>
<!-- This will load your scripts into the document. -->
<script src="js1.js"></script>
<script src="js2.js"></script>
<!--
In a HTML5 page, you don't need to include the
'type="text/javascript"' attribute on script tags.
They're treated as having that by default, unless you say otherwise.
-->
</head>
<body>
<!--
You could also include your scripts here, but I'll
just leave these commented out since they're already included.
<script src="js1.js"></script>
<script src="js2.js"></script>
-->
<script>
js1();
</script>
<!--
You don't need 'language="javascript"' on a script tag.
Use the type attribute, or nothing in a HTML5 page.
-->
</body>
</html>

Categories

Resources