Recently I added to my website facebook like button, twitter follow us button and google +1 button. I want their JS scripts to load when I tell them to load.
Therefore, I need a function that load external JS files. I don't need to know when the file finished to load (callback is not needed).
I found some methods/functions on the Internet, but I want to know which would be the best choice for this situation?
4 ways to dynamically load external JavaScript
Dynamically loading JS libraries and detecting when they're loaded
The best way to load external JavaScript
Thanks.
Edit:
Added the methods/function I found.
I would recommend using jQuery's getScript(). For the twitter-button, you would load the corresponding script like that:
$.getScript("//platform.twitter.com/widgets.js")
Of course you would have to load jquery in your script first and do not forget to add the markup needed for the twitter-button in your html.
This might be helpful:
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
Something like
function getScript(url) {
e = document.createElement('script');
e.src = url;
document.body.appendChild(e);
}
getScript('jstoload.js');
this?
The YUI Loader sounds like a good choice for you. It will also allow you to add your own custom modules, so you can load on demand, as well as load all other JS files that are required as well.
Related
I want to load a web page that's generated by JS (e.g., AngularJS or similar) then scrape it using (only) Google Apps Script. How can I accomplish that?
I'm looking for something like:
const response = UrlFetchApp.fetch( urlToExternalJsPage );
const content = response.getContentText();
// scrape content
Only, maybe, replace the UrlFetchApp with come call to a library or something? Perhaps a Puppeteer library for GAS, the Cheerio library for GAS or something else?
How can I load an externally loaded JS page and read the HTML from that page after it's generated in order to scrape it?
Idea 1
I came across this article: The Best Way to Load Javascript that supplies the following code.
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
The actual code on your page ends up looking like this:
<script type="text/javascript" src="http://your.cdn.com/first.js"></script>
<script type="text/javascript">
loadScript("http://your.cdn.com/second.js", function(){
//initialization code
});
</script>
The problem with this approach is that I'm trying to stay strictly server side. I'm not trying to post any HTML pages and/or serve them.
Idea 2
I came across this article that appears to describe some Puppeteer Libary for GAS. I translated it from Japanese using Google Translate. The problem is it requires using Google Cloud Platform and I want to avoid that. I also want to avoid setting up any billing and just stay strictly inside Google Apps Script.
Idea 3
Perhaps there is a way to use the browser that comes with the UI service. Specifically, the sidebar?
On this page, I found the following example of importing web pages into an HTML service page using an IFRAME.
Code.gs
function doGet() {
var template = HtmlService.createTemplateFromFile('top');
return template.evaluate();
}
top.html
<!DOCTYPE html>
<html>
<body>
<div>
Click Me!
</div>
</body>
</html>
I want to load a javascript from an external source on my site, after clicking on a button.
I tried the following solution. Java script code, which is executed after clicking on the button:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "scrSource";
document.getElementsByTagName("head")[0].appendChild(script);
So now I can see the javaScript in my head, but it was not executed.
So when I load my external script with the normal way (when the page is loading) in the header, it loads a few other java script sources.
But with my solution (load file after clicking a button), I only put it in the head and no further action is happening.
Do someone have any ideas how I can solve this problem? (and I´m not allowed to use jQuery, only java script)
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
loadScript("https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/faker.min.js", function(){
//initialization code
alert('loaded: ' + faker.name.findName());
});
A simple Google search of "Load external javascript" returns this link. The function you see it is from there. It's and old one but it works.
I use Faker.js to generate random data as confirmation that the library loaded is ready to be used.
It handles onreadystatechange/onload so you can define a callback to start using the library you've just downloaded.
I recently found out about load.js, but I can't seem to find any indication of whether or not this is possible... (Note: I can't find a 'load.js' tag..)
I've got load.js successfully loading all my JS files, so I know it works. Has anyone got it working for loading CSS files as well?
Update: remyabel's solution worked perfectly for loading the physical files, but it seems there are a few quirks to this process...
For some reason, the order in which the CSS files are loaded and whether they're all done in one load(file1,file2); or in stages with load(file1).then(file2); seems to affect how the style rules are applied to the markup. I'm going to set up a few test cases on my local machine to try work out how or why this happens, but for now at least the files are being loaded.
Final Note:
Following on from the solution posted below, I've decided to use head.appendChild(script); instead of head.insertBefore(script, head.firstChild); to add the CSS elements to the DOM (still uses the original method for JS files).
This doesn't affect the order in which files are fetched and processed, but it makes Load.js insert my CSS links in the same order they were listed and at the end of the header instead of the beginning.
Direct from the source code
function asyncLoadScript(src) {
return function (onload, onerror) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
My suggestion is to modify the script (which doesn't seem to contain much) to mirror the function but for a link tag, rather than a script tag.
to reflect OP's comment
The script is built on top of chain.js so it may be more complicated than expected.
Unless you want something else, I'm pretty sure what I wrote above is what you need to change, so it would look like:
function asyncLoadScript(src) {
return function (onload, onerror) {
// Get file extension
var ext = src.split('.').pop();
if (ext == "js")
{
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
} else if (ext == "css")
{
var script = document.createElement('link');
script.type = 'text/css';
script.href = src;
script.rel = "stylesheet";
}
Theoretically that should work. Make another comment if it doesn't work.
I have legacy web app situation where I can't load jquery.min.js from a script tag in the HTML markup.. so I have to load it with some js in another existing script file
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
script.type = 'text/javascript';
head.appendChild(script);
The problem is.. when the include load is slow.. there are jQuery functions
(also dynamically loaded on the page) that try to run and can't find jQuery
Is there some cross-browser way to do a callback in the above code that calls the jQuery ready function after the jquery.min.js include file finishes downloading from the CDN? Thanks,
EDIT:
Using Mike's code this is working with onload for nearly all browsers except
IE 8 or earlier.. and other browsers which need onreadystatechange I guess
JSFIDDLE HERE:
http://jsfiddle.net/BmyGC/
try
if(script.onreadystatechange)
script.onreadystatechange = function()
{
if(script.readyState == "complete" || script.readyState=="loaded")
{
script.onreadystatechange = false;
console.log("complete");
}
}
else
{
script.onload = function()
{
console.log("complete");
}
}
I would put my jquery-based code in yet another separate javascript file, and load that file in exactly the same way you are loading the jquery.min.js. Just do so immediately after jquery.min.js. That should work.
edit
Okay, since that isn't working, try this:
function jqChecker()
{
if (! jQuery )
{
setTimeout(jqChecker, 500); // adjust as needed.
}
else
{
// insert code to dynamically load your external js file here
}
}
jqChecker();
The following are the first lines of code in a <script> tag just above the closing body tag in my document (it specifies that a locally-served copy of jQuery is run in the event that Google's CDN fails):
if(!window.jQuery){
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '/js/jquery.js';
var scriptHook = document.getElementsByTagName('script')[0];
scriptHook.parentNode.insertBefore(script, scriptHook);
}
jQuery(document).ready(function($){
// page behaviors
});
It does execute successfully, in the sense that if my computer is not connected to the Internet (this is a locally-served page), the local copy of jQuery is inserted. However, the document.ready() section below does not execute. I'm guessing this is because it is invoked before the fallback copy of jQuery takes effect. What's the proper practice for somehow "delaying" its execution so that either copy of jQuery will work properly?
Consider using an existing script loader such as yepnope. There's an example of exactly what you're trying to do on the home page.
You need to be sure that the script you are appending to the dom has finished loading before calling jQuery. You can do this with the technique described here:
if(!window.jQuery){
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '/js/jquery.js';
script.onreadystatechange= function () {
if (this.readyState == 'complete') jQueryLoaded();
}
script.onload = jQueryLoaded;
var scriptHook = document.getElementsByTagName('script')[0];
scriptHook.parentNode.insertBefore(script, scriptHook);
}
function jQueryLoaded() { };
You can also fetch the jQuery contents as an Ajax request, create a script tag with those as the body of the script and append it. That would also work.
Try that
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.2.min.js"><\/script>')</script>
<script>
jQuery(document).ready(function($){
// page behaviors
});
</script>
This way the script tag will be loaded synchronously.
The question "of how do I cope with my CDN failing and load a file hosted on my server" seems to come up a few times lately.
Question I'd ask is whether adding yet more js is the way to achieve the resilience and what level of resilience do the js approaches really add e.g. if the CDN is down they'll be a quick failure but how well do these approaches if the CDN is slow to respond how well do these solutions cope?
An alternative way to approach this is treat it as an infrastructure problem...
Run a CDN based on a domain/sub-domain you own. Have automated monitoring on it's availability, when it fails switch the DNS over to a backup server (anycast may provide an alternative solution too)
A php solution would be something like this:
$google_jquery = 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js';
$fp = #fsockopen($google_jquery, 'r');
if (!$fp)
{
echo '<script type="text/javascript" src="js/jquery.js"></script>';
}
else
{
echo '<script src="'.$google_jquery.'"></script>' }
}