JavaScript insert script with async and use functions from it? [duplicate] - javascript

This question already has answers here:
Accessing variables after dynamically loading a script
(2 answers)
Closed 8 years ago.
I have written a small widget which I include onto pages like this:
<script type="text/javascript">
var _sid = '1';
(function() {
var se = document.createElement('script'); se.type = 'text/javascript'; se.async = true;
se.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://') + 'dev.domain.com/widget/hello.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(se, s);
})();
</script>
Now I want to find a way to call functions that exist within hello.js, which currently looks like this:
var widget = function () {
function setName(a) {
console.log(a);
}
return widget;
}();
So I want to be able to make a call to setName like so: widget.setName("Andy")
...from the embed page, but for some reason I get "widget is undefined."
Any ideas what I am doing wrong?

Before you use widget, you need to know it is loaded, there are multiple options for that:
Use requireJs or something like it.
Implement a callback function in the javascript you are loading, say it will fire 'document.onHelloIsLoaded', then if you want to know if hello is loaded, just set that variable to a function.
Make a loop, checking if the widget variable is set. setInterval (which cancels itself when widget is found and the code has executed)
you also need to make the setName variable accessible when you have access to widget, which it now isn't. You should put something like this:
var widget = {};
widget.setName = function()...
return widget;

Related

Check if javascript is already attached to a page?

Is there any way to check if javascript file is already attached to the page by its file name.
For eg :
if ("path-to-script/scriptname.js") already embeded
{
call related function
}
else
{
Append '<script src="path-to-script/scriptname.js" type="text/javascript"> </script> '
call related function
}
Basically I dont want 1 script to be attached twice on the same page.
You might not always know what objects or functions a script contains in advance, in such cases you can search for script tags containing the desired src.
With jquery:
$("script[src*='"+scriptName+"']");
Without jquery:
document.querySelector("script[src*='"+scriptName+"']");
You'd need to test whether the actual function from the script file exists, like this:
if (window.function_name) {
// script loaded
} else {
// script not loaded
}
I agree with #zathrus though I think you should be using requirejs for things like this. The idea is that dependencies must be fetched before executing the code. The above method you are using may work but you can not guarantee anything.
RequireJS will beautifully maintain all the dependency loading. It is very easy to learn as well.
Simply check if the library is defined, otherwise import it:
if ( !jQuery ) {
var s = document.createElement('script');
s.type = 'text/javascript';
document.body.appendChild(s);
s.src = "path-to-script/scriptname.js";
void(0);
}
// call function
you really need a script loader.. because as you said you want it specific with the javascript resource filename and this is sort of your javascript files are depending to each other
www.headjs.com
www.modernizr.com
www.yepnopejs.com
I thought this will help you.
if (typeof scriptname== "undefined") {
var e = document.createElement("script");
e.src = "scriptname.js";
e.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
}

Is it possible to execute Javascript code that was retrieved using pjax?

Let's say I have some simple Javascript like:
<script>
var hello = function(){
alert("Hello World!");
}
</script>
.. on a page helloworld.html. If I loaded this script block into another page using Pjax. How do I execute the function hello()?
For security reasons, many browsers will not run Javascript injected by innerHTML, which I'm thinking Pjax likely uses. (Here's a minimal example.)
Maybe the solution proposed in Pjax's issue #48 will help
What worked for me was to place my jQuery code in a function, call it
normally on document.ready (for non-pushState browsers), and then bind
the function to pjax:end, i.e.:
$('body').bind 'pjax:end', mainFunction
This is possible with PJAX. You just need to have the script tag with type text/javascript.
Code from PJAX library:
function executeScriptTags(scripts) {
if (!scripts) return
var existingScripts = $('script[src]')
scripts.each(function() {
var src = this.src
var matchedScripts = existingScripts.filter(function() {
return this.src === src
})
if (matchedScripts.length) {
matchedScripts.remove();
}
console.error("FOUND SCRIPTS", scripts, matchedScripts.length);
var script = document.createElement('script')
script.type = $(this).attr('type')
script.src = $(this).attr('src')
document.head.appendChild(script)
})
}

JavaScript: Accessing Variables Defined in External .js Files [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dynamically Importing JavasScript
Is there a way to access variables which come from external imported JavaScript .js files?
In the external .js file I define a varialbe such as follows:
// JavaScript Document
var PETNAME = "Beauty";
After dynamically importing that code, I wish to access PETNAME variable, but I do not get the defined value:
alert("Pet Name: " + PETNAME);
What can be wrong, and is there a way to bring values from external .js code into the master JavaScript?
Thank you.
To import JS dynamically, you need to consider onreadystatechange and load events which are run when the script is parsed by the browser and available to you. You can use this function:
function getScript(url, callback) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
script.onreadystatechange = callback;
script.onload = callback;
document.getElementsByTagName('head')[0].appendChild(script);
}
And you can use it like this:
getScript('path to your js file', function(){
alert("Pet Name: " + PETNAME);
});
Make sure you are including external file before trying to access variable defined in it. Also make sure the variable in the external file is not defined inside function, in which case they range is limited to that function only. If this not helps try removing keyword var before variable, this will create global variable.

Javascript, async, send custom var

I'm using the following code http://friendlybit.com/js/lazy-loading-asyncronous-javascript/ to make async calls but now I want to send custom var to this script and cannot figure it out.
(function() {
function async_load(){
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://yourdomain.com/script.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
}
if (window.attachEvent)
window.attachEvent('onload', async_load);
else
window.addEventListener('load', async_load, false);
})();
Now I want to have custom var that is sent to "script.js". That's all, a simple var to be sent to JS. I've even tried by using query strings but no results.
Help please.
Just assign it to the global scope (with window.varname = value for example) and the script you load will be able to use it, since it runs on the same page.
What do you mean send to script ? Loaded script can access page and all global variables. Just declare global variable and your script can access in regular way.

Can't access variables from dynamically loaded javascript

I'm using a fairly simple system to load javascript dynamically:
include = function (url) {
var e = document.createElement("script");
e.src = url;
e.type="text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
};
Let's say I have a file test.js which has the following contents:
var foo = 4;
Now, in my original script, I want to use
include(test.js);
console.log(foo);
However, I get a 'foo has not been defined' error on this. I'm guessing it has to do with the dynamic script being included as the last child of the <head> tag. How can I get this to work?
It is because you have to wait for the script to load. It is not synchronous like you would think. This may work for you:
include = function (url, fn) {
var e = document.createElement("script");
e.onload = fn;
e.src = url;
e.async=true;
document.getElementsByTagName("head")[0].appendChild(e);
};
include("test.js",function(){
console.log(foo);
});
That is one problem, but it also takes time for the browser to download and parse the remote JS file — and it hasn't done that before you call console.log.
You need to delay things until the script has loaded.
This is easiest done by letting a library do the heavy lifting, jQuery has a getScript method that lets you pass a callback to run when the script has loaded.

Categories