I am trying to develop an embeddable widget. This widget renders some UI elements into the customer's page.
This widget will look like this:
<script src="//example.com/widget.js?param1=a¶m2=b" async></script>
A user is allowed to embed multiple widgets on a single page, each with a different set of parameters.
Within this widget script, I am trying to load other javascript and css files required to render my widget.
This is the function I am using to load other javascript files.
function loadScript(scriptUrl) {
var s = document.createElement('script');
s.async = true;
s.src = scriptUrl;
document.body.appendChild(s);
}
The problem is that each script loaded this way is loaded multiple times, when there are more than one embeds per page.
How do I make sure each file is loaded only once?
For example, I try to load a jQuery reference inside that loader script, I see that if I embed my widget 5 times, there are 5 calls to the jquery library.
3 extra lines of code
var scripts = {}; //record what is loaded
function loadScript(scriptUrl) {
if (scripts[scriptUrl]) return; //exit if loaded
scripts[scriptUrl] = 1; //mark that it is loaded
var s = document.createElement('script');
s.async = true;
s.src = scriptUrl;
document.body.appendChild(s);
}
Related
I want to load <div> content dynamically by using AJAX in a specific div. After the AJAX call I want to load a JS file in the footer. I loaded content by clicking menu without page loading by using URL hash. My problem is when I click the same link multiple times, the JS file is loading multiple times because the JS file is appended. That's why every event occurs multiple times. I want to load the JS file before checking if the file is already loaded into the DOM. If the file is not loaded in the DOM, I will append a JS file in the DOM.
As the answer suggested by this URL, here is my code:
var Utils = {
loadjs: function(url){
var footer = document.getElementsByTagName('body')[0];
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
footer.appendChild(script);
},
}
Utils.loadjs(url);
You can read the script tags to search for a particular script is there or not. Something like below:
var Utils = {
loadjs: function(url) {
var me = document.querySelectorAll('script[src="' + url + '"]');
if (me && me.length >= 1) {
return null;
}
var footer = document.getElementsByTagName('body')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
footer.appendChild(script);
},
}
Utils.loadjs(url);
You can use dynamic import() syntax to load modules, even from regular scripts.
This has the benefit of loading those scripts as modules, which are always in strict mode and have module scope.
Read more about dynamic import
So, instead of Utils.loadjs(url), just import(url)
I was given a javascript line that calls a javascript file which is made by a company called walkme.
I have an app/assets/javascript/application.js file that calls all of my jquery that I am using for the site. for example it contains:
require feed
which calls feed.js when someone is on the feed page. I would like the walkme.js to also be called at the same time this code is called
I am looking for a way to add this <script ... code to a ruby site that uses slim and jquery.
<script type="text/javascript">(function() {var walkme = document.createElement('script'); walkme.type = 'text/javascript'; walkme.async = true; walkme.src = 'https://cdn.walkme.com/thewalkme.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(walkme, s); window._walkmeConfig = {smartLoad:true}; })();</script>
I have tried a blunt style of just making a walkme.js in the same place as the feed.js and putting that <script ... code in that file while adding the necessary require walkme code, but that seems to do nothing.
Some info:
Ruby on Rails
Ruby 2.1.7p400
ubuntu 14.04 LTS server
some files are named *.html.slim
As you may be able to tell, I did not make all the ruby code and am not an expert in ruby, javascript or jquery.
If this was just an html site, I think could just add the line of code to the header.
Mostly, Javascripts are called after the page has finished loading, since you want to manipulate the DOM, most likely.
So, you either don't want to call the script in the head of your document, unless you have a document.ready in the script.
To answer your question then, if you want the following script:
function(){
var walkme = document.createElement('script');
walkme.type = 'text/javascript';
walkme.async = true;
walkme.src = 'https://cdn.walkme.com/thewalkme.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(walkme, s);
window._walkmeConfig = {smartLoad:true};
};
to be available only on the feed page of your application,
You can make this function a named function, in a separate file (say feed.js.coffee for example) and call the function in your slim view page as follow:
//feed.js.coffee:
#feed = ->
walkme = document.createElement('script')
walkme.type = 'text/javascript'
walkme.async = true
walkme.src = 'https://cdn.walkme.com/thewalkme.js'
s = document.getElementsByTagName('script')[0]
s.parentNode.insertBefore walkme, s
window._walkmeConfig = smartLoad: true
return
and in your view:
/feed.html.slim:
...
your codes...
...
coffeeview:
feed
Developing phonegap application which loads google map. Using below two javascript for google map. One javascript is loaded from locally while other javascript loaded from server.
var script = document.createElement('script');
script.src = 'http://maps.google.com/maps/api/js?sensor=true';
script.type = 'text/javascript';
document.head.appendChild(script);
script.onload = function () {
var script1 = document.createElement('script');
script1.src = 'js/jquery.ui.map.js';
script1.type = 'text/javascript';
document.head.appendChild(script1);
script1.onload = function () {
alert(google.maps.LatLng);
}
};
Both javascripts should be loaded after html page is loaded. Tried below code and referred various blogs, but its not working.
If same scripts written in header tag of html page, then it working perfectly. but in my application i need it to be loaded dynamically.
Please help....
Solved:
var doc_write = document.write; // Remember original method;
document.write = function(s) {$(s).appendTo('body')};
$.getScript('http://maps.google.com/maps/api/js?sensor=true').done(function()
{
$.getScript('js/jquery.ui.map.js').done(function()
{
document.write = doc_write; // Restore method
setTimeout(function()
{
alert(google.maps.LatLng);
},1000);
})
.fail(function(jqxhr, settings, exception)
{
alert(exception); // this gets shown
document.write = doc_write; // Restore method
});
}).fail(function()
{
alert('failed to load google maps');
});
Problem:
It takes some time to initialise.
Call your javascript function after device get ready function. Because if you are using phone gap through Xcode, the device get ready function take some time to load and your script is called before it.
Don't do it in this way
Load it in footer section of your application
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.
I am loading scripts and style-sheets dynamically from javascript like this.
The problem is that browser does not wait for the script to load.
consider i have a function named functionToBeCalled() inside a script file named script-file.js
i have a function to load script file.
<script type="text/javascript">
var listOfJavaScriptsLoaded = new Array();
function LoadScriptFile(scriptUrl){
var isScriptLoaded = false;
var i = 0;
for(i = 0; i < listOfJavaScriptsLoaded.length; i ++){
if(listOfJavaScriptsLoaded[i] == scriptUrl){
isScriptLoaded = true;
break;
}
}
if(isScriptLoaded == false){
var headTag= document.getElementsByTagName('head')[0];
var scriptTag= document.createElement('script');
scriptTag.type= 'text/javascript';
scriptTag.src= scriptUrl;
headTag.appendChild(scriptTag);
listOfJavaScriptsLoaded.push(scriptUrl);
}
}
LoadScriptFile("script-file.js");
functionToBeCalled();
</script>
now, what happens is that the browser does not wait for the script tag to load and goes to the next command. I get a "undefined functionToBeCalled()" error. this is natural. But the fact is that when i inspect in firebug, the script tag has been formed and the file has loaded.
So how do i make the browser to pause loading and resume after the asset has been loaded?
Edit1: This problem occurs only when i am loading the page in ajax and not in normal page loads
Edit2: Or is there a possibility to read a script/css file from javascript and write it directly in the markup within script tags
If i use window.stop() the loading stops completely. how can i make it resume from the same line?
Or is it possible to make the browser to consider that the loading is still happening and reset it in the onload event?
You may have specific reasons to load the script dynamically, but to present the option, if you write out the script element in your HTML output like so:
<script src="script-file.js"></script>
<script>functionToBeCalled();</script>
the browser will halt parsing until that script has been loaded, and interpreted.
This is also valid in the BODY.
Check out LABjs ( http://labjs.com/ ) by Getify Solutions. LABjs allows script-inserted scripts to be loaded concurrently but run in order.
pretty much every tag which loads a resource has an onload event. so in plain javascript this means in your case something like this:
var s = document.createElement('script');
s.src = "script-file.js";
s.type = 'text/javascript';
head.appendChild(s);
s.onload = function(){
functionToBeCalled();
}
I would recommend looking at Cuzillion. It will allow you to experiment with calling javascript and css in many different ways to see how they react in the browser.
This should answer your question. Just execute it before your page is done loading the body.
<script type="text/javascript">
var loadScriptFile = (function(){
var listOfJavaScriptsLoaded = [];
return function(scriptUrl){
var isScriptLoaded = false;
for(var i = 0; i < listOfJavaScriptsLoaded.length; i ++){
if(listOfJavaScriptsLoaded[i] == scriptUrl){
isScriptLoaded = true;
break;
}
}
if(!isScriptLoaded){
document.write('<scr' + 'ipt type="text/javascript" src="' + scriptUrl + '"></scr' + 'ipt>');
}
};
}());
loadScriptFile("script-file.js");
functionToBeCalled();
</script>