I'm adding a javascript pixel tracker onto a website, but I'm only trying to have it display on a specific circumstance. That circumstance is being tested for in an external javascript file which then creates the HTML code to echo out.
My question is can the pixel tracking script just stay within that external javascript file? As in not be apart of the echoed out HTML Code that would display in a View Source of the page, and just stay hidden within that external js.
Here is the bulk of the tracking code:
(function () {
var oldonload = window.onload;
window.onload = function(){
__adx_loaded=true;
var scr = document.createElement("script");
var host = (("https:" == document.location.protocol) ? "https://adx.com" : "http://adx.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()}};
}());
Yes it can be in an external javascript file.
Related
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.
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.
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);
}
The company which developped my website just added this javascript code on the Zend Guard encrypted index.php file (I saw it with "View source") :
(function ()
{
var smrs = document.createElement("script");
smrs.type = "text/javascript";
smrs.async = true;
smrs.src = document.location.protocol + "//www.domain.com/file.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(smrs, s);
})();
It injects a very agressive javascript code which adds a image link to their website (with a SetInterval each 10sec), at the bottom of the page.
The problem ? A local competitor, which is currently being accused of significant fraud, have the same CMS and the same image link.
Being associated with that competitor is prejudicial for me. I would like to know if there is a way to block the "www.domain.com/file.js" loading with a .htaccess.
Thanks.
You can't (using htaccess). This javascript creates a script tag to load the external javascript. The call never passes through the server. So apache (htaccess) can't block that.
The easiest way is to search in the source code and remove the script (if you have access).
UPDATE:
I see the script is encrypted... If you can insert a script at the very beginning (before the code gets executed you can create a hook on the insertBefore method. Here is a working fiddle
var ALLOWED_DOMAINS = ['www.klaartjedevoecht.be', 'jsfiddle.net'];
function creatHook(){
function getDomain(url) {
return url.match(/:\/\/(.[^/]+)/)[1];
}
var insertBefore = Element.prototype.insertBefore;
Element.prototype.insertBefore = function(new_node,existing_node){
if(new_node.tagName.toLowerCase() === 'script' && ALLOWED_DOMAINS.indexOf(getDomain(new_node.src)) > -1){
insertBefore.call(this, new_node, existing_node);
}
}
}
creatHook();
//TESTING CODE:
var smrs = document.createElement("script");
smrs.type = "text/javascript";
smrs.async = true;
smrs.src = document.location.protocol + "//www.klaartjedevoecht.be/test.js";
//var smrs = document.createElement("img");
// smrs.src= "http://img52.imageshack.us/img52/7653/beaverl.gif";
var s = document.getElementsByTagName("div")[0];
s.parentNode.insertBefore(smrs, s);
I agree it's a bit hacking, but at least its cleaner then the timer solution. If you can't remove it, there is no clean solution.
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.