How to dynamically load a file on a specific line in JavaScript? - javascript

I created this script for a core.js file for my client's website and I want to dynamically load a few javascript libraries from that core.js file. However, javascript libraries require that you load that library first, then use the rest of your script, because you have to define your libraries object before calling it, doh. So I have this very simple script to dynamically load a file, but I want to know if there's a method to make sure that it loads it in priority ahead of the core.js file. Here's the current script:
(function() {
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", "http://modernizr.com/downloads/modernizr-latest.js");
if(typeof script != "undefined") {
document.getElementsByTagName("head")[0].appendChild( script );
}
})();
And in the debugger, you see:
Of course, it's going to load the dynamic file ahead of the core file, but I was wondering if there was a way to specify the line on the document for which to load the modernizr file? Otherwise, I can't use Modernizr, even though I have loaded it.
Obviously, I can't use jQuery, because I want to load that, too.

You can respond to the loading of a dynamically-loaded JavaScript resource (or any resource, for that matter -- image, iframe, video, etc.) with a load event listener. The easiest way to do it here would be:
(function() {
var script = document.createElement("script");
...
script.onload = function() {
// this will run later, when the script loads
// in this function you can safely use Modernizr
}
})();

Related

When importing an ES6 module, is the path relative to the HTML file or to the JS file?

I want to write a Javascript library, and I want the user to only import the library's main file in his HTML page. However, I saw that if I use tricks like
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL
document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}
(credits https://stackoverflow.com/a/950146/11108302)
the paths to the scripts to include have to be computed starting from the HTML file, which means the user has to put the file in a specific position in order for this to work.
I was wondering whether it could be worth it to rewrite the files to include as ES6 modules. Would doing this make the path to the script relative to the Javascript file including it? If not, how do large libraries handle this?

Loading external javascript in a Chrome Extension

I'm trying to load some external javascript code in my Chrome extension. However, due to the sandboxed environment of the extension, I can't see any of the functions defined by the external code.
The external code implements a dependency mechanism, whereby one javascript file may require another, and so forth. It also looks at arguments to the URL used to load the javascript to determine the top level javascript file to load. So it basically is able to load any arbitrary web app, and it is not known in advance all the files that will be used. So I can't use any static definitions in the extension.
There is also the issue that since all extension code is sandboxed, I don't have complete access to the document - for instance, it can't access the window variable.
But if I put all the code in the external code, I run into content security problems if one script tries to load another. The whole reason I went was an extension is because of the bone-headed misimplementation of CSP by every single browser in existence whereby bookmarklets can't access external resources.
What's the best practice for bypassing or working around the extension sandbox to basically be able to run code as if the page itself had loaded it, without any issues with CSP?
In the content script you could do something like this to load the js file
function inject(url, exteral) {
// 1. Build the absolute URL
// 2. Create a script tag and set src attribute
// 3. Append script tag to thw window
if (!external){
url = chrome.extension.getURL(url);
}
var scriptElement = document.createElement('script');
scriptElement.src = url;
(document.body || document.head || document.documentElement).appendChild(scriptElement);
}
If the js file is packged with the extension, it must be placed in the
manifest.json under web_accesible_resources.
othwerwise it need to have the same protocol that the page it is injected in (http | https)
Since the content script is not allowed to call the window functions, you could
call window.postMessage to send data from the actual window to content script.

including external javascript file

I am trying to include external javascript to a document. Let's say that external js has the following code.
function myFunction() {
console.log("hello");
}
and I include it from console by
var script = document.createElement('script');
script.src = "http://myjs";
document.getElementsByTagName('head')[0].appendChild(script);
but then I still get myFunction() is undefined error. The function is being called from php file included on the page somehow. Interestingly, appending my external javascript right after the head tag in the document was not enough for it to precede the function call from the loaded php file.
Q: how do I ensure that I include my javascript BEFORE the php file given my situation?
EDIT: this is the hierarchy of all the sources
mysubsite.com
myfolder
mypage.html
mysite.com
myfolder
main.php
problem.php
problem.php is calling function myFunction() but it's not included anywhere yet. So I try to define the function in an outside js file and include it in mypage.html, but problem.php still comes before the included javascript in mypage.html
EDIT:
I think the real problem is that I am dealing with an iframe that's included inside a main document. In this case, is there a way to include my external javascript file inside the main document from console? Including scripts from console only affects the iframe instead of the main document.
What you're doing is fine, but then you have to wait for the file to load. Most browsers will raise the load event on the script element although some older versions of IE use onreadystatechanged instead. But since you're using jQuery (from the tags on the question), you don't have to worry about that, you can just use $.getScript:
$.getScript("http://myjs", function() {
// The script has been loaded, you can call myFunction now
});
PHP is always included before JavaScript. PHP is executed by the server before it's sent to the client, and JavaScript is executed by the client.
Why can't you just put a regular <script type="text/javascript" src="http:/myjs"></script> in your head?

How can I prevent an external script from overriding my main.js configuration

I'm building an application using require.js. For a certain part I need to load a 3rd-Party script that is built using require.js as well (it's all minified and built into a single file using almond.js).
For this I inject the script tag like:
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.onload = function(){
// remote widget script has loaded
scriptDfd.resolve();
};
script.src = endpoints.widgetScript + '?appKey=' + auth.userAppKey + '&dev=1';
document.getElementsByTagName('head')[0].appendChild(script);
The script gets injected fine and is working, but from that point on I cannot use the module mapping defined in my own main.js anymore.
The error that is thrown when I try to access my modules is Uncaught TypeError: Cannot read property 'splice' of undefined which sounds like it's not able to find the module anymore (which is easily accessible before I inject the 3rd party script).
Is there any feasible workaround for this?
So, as proposed in the comments I contacted the vendor of the external script (that is actually just dogfooding the dogfooding of another in-house product) and they used a custom namespace when running the r.js build script as described here.
This creates two seperate require.js's that can be configured differently.

Using Javascript to load other external Javascripts

I have a library of JS code to load from a folder.
Instead of typing the <script src='...'></script> lines one by one in the tag of the HTML document, is there a way of just link one Javascript file which organizes and automatically load other javascript files.
I know the Dojotoolkit is using this technique where only one JS file is loaded onto the client's computer, and once the code has been requested in the browser, 20 other JS code each with <script> tag are generated.
This is the code you need:
// Create
var bodyEl = document.body;
var scriptEl = document.createElement('script');
scriptEl.type = 'text/javascript';
scriptEl.src = url;
bodyEl.appendChild(scriptEl);
Put that into a function, have an array of all the javascript files, and call that function for each file.
Benefits of using the DOM is that document.write doesn't work in some funny instances. More about this here:
document.write() vs inserting DOM nodes: preserve form information?
Code taken from the open source project jQuery Sparkle:
http://github.com/balupton/jquery-sparkle/blob/master/scripts/resources/jquery.appendscriptstyle.js#L103
A simple way to do that:
document.write("<script type='text/javascript' src='b.js'></script>");
Try use requireJs, he have very userful functions
Official website

Categories

Resources