Dynamically include javascript code from within javascript file - javascript

I'm inserting the following script, which is on my own server, into an external page of a 3rd party: www.test.com/test.html:
<script type="text/javascript">
(function() {
var protocol = (("https:" == document.location.protocol) ? "https://" : "http://");
var ttScript = document.createElement('script');ttScript.async = true;
ttScript.src = '//www.example.com/script/mycode.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ttScript);
})();
</script>
This is the other script I want to dynamically inject, please note that it can't just be added to the above script! I want this script to be dynamically available.
This complete code, will later be stored within object message.jsScript
<script type="text/javascript">
var tt_totalordervalue;
function tt_getordervalue(){
tt_totalordervalue=$('#subtotal');
console.log(tt_totalordervalue);
}
</script>
In file mycode.js:
I want to dynamically add the above script and call the function tt_getordervalue defined in there, I'm now trying to do this as below. Notice that I also want to assign the value of variable tt_totalordervalue which is defined in the dynamic script, to a variable in my mycode.js:
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(message.jsScript);
console.log('script added');
tt_getordervalue();
console.log('function called');
var val = tt_totalordervalue;
I however then get the error Uncaught NotFoundError: Failed to execute 'appendChild' on 'Node': The new child element is null.
Why?

Following works on chrome on a Mac (sorry, was too lazy to cross test):
var script = document.createElement('script');
script.innerHTML = 'window.doStuff = function(){alert("do")}';
document.getElementsByTagName('body')[0].appendChild(script);
doStuff();

Related

Reduce number of third party asynchronous call from client

I have an application in which the client sends multiple asynchronous javascripts requests to the third party servers. The problem which I am facing is that whenever the client responds to these responses the site becomes inactive for that miliseconds period of time. So sending these multiple requests increases the inactive time. For example if I send x requests and lets assume for each reponse that site becomes inactive for y avg miliseconds and then total inefficient time is x*y. How can I reduce these calls into one call. Third party which I am referring are like calls for google analytics , google ad leads and many more
Here is the example of one of the calls I am making
function () {
var oldonload = window.onload;
window.onload = function(){
__adroll_loaded=true;
var scr = document.createElement("script");
var host = (("https:" == document.location.protocol) ? "https://s.adroll.com" : "http://a.adroll.com");
scr.setAttribute('async', 'true');
scr.type = "text/javascript";
scr.src = host + "/j/roundtrip.js";
((document.getElementsByTagName('head') || [null])[0] ||
document.getElementsByTagName('script')[0].parentNode).appendChild(scr);
if(oldonload){oldonload()}};
}());
First of all: inline async javascript does not block browser. But immediately invoked function does. You don't need to nest window.onload callback into the immediately invoked function.
I recommend you to provide one function doing all things in reaction to browser event. As an example:
window.onload = function() {
//do everything here
}
If it is possible by your app logic put this script right before </body> closing tag.
This might help you. Anyway I also recommend you to measure what your app really doing when script executes. You can do this easily, for example, with chrome developer tools (timeline tab).
The problem might be with how adroll is hijacking the window.onload, which fires after all page rendering is done. If I were you, I'd use jQuery (one of the other things you're calling already likely is, so get it from the Google URL so you only have to download it once). Put it right at the top of your HEAD tag, so that it downloads and loads first, and for YOUR code, use a $(document).ready() call, like this:
<!doctype html>
<html language="en">
<head>
<title>My Webapp</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--// other library scripts go here -->
... the rest of the HEAD and BODY
<!--// other paste-in tracking code scripts like Google Analytics go here-->
<script>
$(document).ready(new function () {
//Your onload code, which should no longer be blocked
});
</script>
<script type="text/javascript"> //followed by your adroll script
(function () {
var oldonload = window.onload;
window.onload = function(){
__adroll_loaded=true;
var scr = document.createElement("script");
var host = (("https:" == document.location.protocol) ? "https://s.adroll.com" : "http://a.adroll.com");
scr.setAttribute('async', 'true');
scr.type = "text/javascript";
scr.src = host + "/j/roundtrip.js";
((document.getElementsByTagName('head') || [null])[0] ||
document.getElementsByTagName('script')[0].parentNode).appendChild(scr);
if(oldonload){oldonload()}};
}());
</script>
</body>
</html>
This way the scripts will download quietly in the background, and your code can go on and do what it needs to do without them. If it's really the scripts that are blocking your code for running, you can set a timeout function to delay it from loading for half a second or so while your code loads, by changing it like so:
<script type="text/javascript"> //followed by your adroll script
(function () {
var oldonload = window.onload;
window.onload = function(){
setTimeout(function () {
__adroll_loaded=true;
var scr = document.createElement("script");
var host = (("https:" == document.location.protocol) ? "https://s.adroll.com" :
"http://a.adroll.com");
scr.setAttribute('async', 'true');
scr.type = "text/javascript";
scr.src = host + "/j/roundtrip.js";
((document.getElementsByTagName('head') || [null])[0] ||
document.getElementsByTagName('script')[0].parentNode).appendChild(scr);
}, 500);
if(oldonload){oldonload()}
};
}());
</script>
This way, it immediately goes on to do whatever window.onload was supposed to do for your own code, and half a second later, the adroll code will execute asynchronously.
To actually reduce number of js requests you can use bundling on the server. This will allow you to have single request to the server which will grab all necessary js-files and put them in a single response body.
So instead of doing something like this:
<script src='https://s.adroll.com/js/javascrpt1.js' type='text/javascript'></script>
<script src='https://s.adroll.com/js/javascrpt2.js' type='text/javascript'></script>
....
<script src='https://s.adroll.com/js/javascrpt100.js' type='text/javascript'></script>
You can make only one call
<script src='https://yourdomain/getAllJs' type='text/javascript'></script>
You can also implement it in a way that will be more reusable, for example you can pass filenames of the scripts you need on certain page.
<script src='https://yourdomain/getjs?file=javascript1.js&file=javascript2.js&....file=javascript100.js' type='text/javascript'></script>
I'm no sure what server technology you are using, so I didn't put an sample here. In ASP.NET for example you can use Bundling and Minification out of the box.

Send variable to external PHP file from JavaScript

I have the following code to include in one domain (http://www.example1.com)
<script
type="text/javascript"
src="http://www.example2.com/API/incoming.php?id=560">
</script>
All this does is invoke the page incoming.php in my second domain (http://www.example2.com), and send it the value "560".
My questions are:
Is it possible to send runtime variables to the page? (Eg : I am hard coding `560`, is there any way to get it dynamically if it is part of the URL?
Would it be possible to send the page URL where this script was loaded? This is what I tried so far, but I am not able to access the variable URL.
<script type="text/javascript" src="http://www.example2.com/API/incoming.php?id=560">
var Url = "";
if (typeof this.href != "undefined") {
Url = this.href.toString().toLowerCase();
}else{
Url = document.location.toString().toLowerCase();
}
</script>
you can create the script tag dynamically and pass all the variables you like via GET.
<script>
(function() {
var id = 560;
var url = document.location.toString().toLowerCase(); // use other means if necessary
var scriptElement = document.createElement('script');
scriptElement.src = 'your.php?id=' + encodeURI(id) + '&url=' + encodeURI(url);
document.body.appendChild(scriptElement);
}());
</script>
the scriptElement will begin to load after it is inserted in the document.
this is how google analytics and others did or do it.

Asynchronous PHP page loading within javascript tags

I have the following tag which loads a PHP and I need it to be loaded asynchronously thus everything in the containing page is load even if the called PHP file takes longer to return the value (or even is server is down).
<script language="JavaScript"
src="http://www.server.com/phpfile.php">
</script>
I've tried replacing it with the code use by FB and other methods for JS asynchronous loading but it does not work. The issue is that in this case it is a PHP file the one that is called, not a JS file.
I tried the following but it does not work when the called PHP script plugs HTML code (such as a div with an image) with document.write:
<script language="JavaScript">
(function () {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true; s.src = 'server.com/phpfile.php';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
</script>
Any ideas?
Thank you.

Generate script block containing custom language at runtime

I'm including a funky script (from the german social network VZ) in my page which requires me to insert a script block containing a custom "language":
<script type="vz/login">
client_id : c47a1d7f134b88c9f12448e08f2ef7289e9fc8
redirect_uri : http://game.example.com/vzcallback.html
callback : logResponse
fields : emails,gender,birthday
</script>
Can I insert such a block into my page at runtime using Javascript (no PHP or other server-side code)? I need this to set client_id dynamically.
Additionally I also need to insert something like:
<script src="https://secure.studivz.net/Js/id/v4/library.js"
data-authority="platform-redirect.vz-modules.net/r"
data-authorityssl="platform-redirect.vz-modules.net/r" type="text/javascript">
</script>
But I don't think adding those data-attributes will be a hard challenge.
Yes you can,
var el = document.createElement("script");
el.setAttribute("type","vz/login");
el.innerHTML = "client_id : "+new_client_id
+"\nredirect_uri : http://game.example.com/vzcallback.html"
+"\ncallback : logResponse"
+"\nfields : emails,gender,birthday";
document.body.appendChild(el);
For the second snipped use
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = 'https://secure.studivz.net/Js/id/v4/library.js';
newScript.setAttribute("data-authority","platform-redirect.vz-modules.net/r");
newScript.setAttribute("data-authorityssl", "platform-redirect.vz-modules.net/r");
headID.appendChild(newScript);
You can add the vz/login script node to the dom at runtime. But you need to ensure that the vz/login node has been added before the JS that is looking for it.

How do I dynamically load Google Analytics JavaScript?

Without using any other JS frameworks (dojo, jquery, etc), how would I dynamically load Google Analytic's javascript to be used on a web page for web-tracking?
The typical appropriate to dynamically loading JS is to do the following:
var gaJs = document.createElement("script");
gaJs.type = "text/javascript";
gaJs.src = "http://www.google-analytics.com/ga.js";
document.body.appendChild(gaJs);
var pageTracker = _gat._getTracker("UA-XXXXXXXXX");
pageTracker._initData();
pageTracker._trackPageview();
But that doesn't work.
The ga.js file isn't loaded in time for _gat._getTracker & _initData/TrackPageview to function.
Any ideas on how to properly dynamically load ga.js.
UPDATE: Seems like someone has attempted to address this problem at the following link. However, it's for use with the old Urchin code and not Google Analytics.
Any ideas on how to get this to work with ga.js instead of urchin.js?
http://20y.hu/20070805/loading-google-analytics-dynamically-on-document-load.html
You could use this snippet from HTML5 Boilerplate.
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
<script>
var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
Server side programming would be easier I guess, but I found this some time ago. Notice that it specifically sets it to the html head.
Also check on the first link down on 'Adding Javascript Through Ajax'.
Try using the exact JavaScript code provided by Google and then conditionally display that section of code based on a construct in your UI framework. You didn't say what platform this is running on, if it's ASP.NET you could put the code in a PlaceHolder or UserControl and then set Visible to true or false based on a config file setting if the script should be included. I've used this approach on multiple sites to prevent the Analytics script from being included in pre-production environments.
function loadGA()
{
if(typeof _gat == 'function') //already loaded
{
//innitGA();
// you may want the above line uncommented..
// I'm presuming that if the _gat object is there
// you wouldn't want to.
return;
}
var hostname = 'google-analytics.com';
var protocol = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
js = document.createElement('script');
js.setAttribute('type', 'text/javascript');
js.setAttribute('src', protocol+hostname+'/ga.js');
document.body.appendChild(js);
//2 methods to detect the load of ga.js
//some browsers use both, however
loaded = false; // so use a boolean
js.onreadystatechange = function () {
if (js.readyState == 'loaded')
{
if(!loaded)
{
innitGA();
}
loaded = true;
}
};
js.onload = function ()
{
if(!loaded)
{
innitGA();
}
loaded = true;
};
}
function innitGA()
{
//var pageTracker = _gat._getTracker('GA_ACCOUNT/PROFILE_ID');
//pageTracker._initData();
//pageTracker._trackPageview();
alert('oh hai I can watch plz?');
}
just call loadGA()... tested on IE6/7/8, FF3, Chrome and Opera
sorry if I'm a bit late to this party.
I've literally just put something together that does this... using jquery. The trick is to add a load event to the script tag with the tracking code in it.
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
var gaScript = document.createElement('script');
var loaded = false;
gaScript.src = gaJsHost + "google-analytics.com/ga.js";
$(gaScript).load(function(){
loaded = true;
var pageTracker = _gat._getTracker(Consts.google_analytics_uacct);
pageTracker._initData();
pageTracker._trackPageview();
});
document.body.appendChild(gaScript);
// And to make it work in ie7 & 8
gaInterval = setInterval(function() {
if (!loaded && typeof _gat != 'undefined') {
$(gaScript).load();
clearInterval(gaInterval);
}
},50);
The thing i'm trying to work out is... is this allowed by google.

Categories