Javascript link tracking script + Safari - javascript

I'm trying to make a link tracking script. It should work like Google Analytics only it should make posts to our own server. I'm using jQuery for this. The code i have written so far is the following:
jQuery(document).ready(function() {
var opts;
jQuery.fn.trackAllLinks = function(settings) {
settings = jQuery.extend({}, jQuery.fn.trackAllLinks.defaults, settings);
opts = settings;
function track() {
href = jQuery(this).attr('href');
var trackImage = new Image(1, 1);
trackImage.src = opts.linkredirector + '?eurl=' + jQuery.URLEncode(href) + '&rnd=' + new Date().getTime() + '&title=trackerimage.gif';
trackImage.onload = function() {
trackImage.onload = null;
doNothing();
}
delay(300);
return true;
};
function delay(mseconds) {
var currentTime = new Date();
var endTime = currentTime.getTime() + mseconds;
while (currentTime.getTime() < endTime) {
currentTime = new Date();
}
}
function doNothing() {
}
if(jQuery(this).is("a")) {
jQuery(this).click(track);
}
jQuery(this).find("a").click(track);
};
jQuery.fn.trackAllLinks.defaults = {
linkredirector : '__url_to_post_on__'
};
});
It works fine in all browsers except Safari. When i'm using a mailto link or an anchor it works but when i'm linking to another page it doesn't work. I have been testing a lot of different implementations and i can't get it to work. Any of you have an idea what i'm missing? I have tried to understand how Google Analytics works and as far as i can see it does the same. When i use WireShark to monitor my network i see that the image of Google is being requested but that my image isn't.
greets,
Daan

This is random, but you might try adding a randomized parameter in the query string (both the name & value), like:
Math.random(0, 1000) + '=' + Math.random(0, 1000)
I've had to do that in the past to get Safari to register a dynamically loaded resource.
(I see you have &rnd= already, but maybe try randomizing the name, too?)

Related

Random behaviour of SWF loading

I have a really strange behiavour with the loading of a SWF file: the buttons on it are working on the first load, but if I reload the page they don't work anymore, even if I empty my cache or force SWF reload by appending a random parameter at the end of the URL. The buttons are generated from a XML file called in the init function.
Here is how I call my swf :
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script
<script type="text/javascript">
// <![CDATA[
window.onload=function(){
var _time = (new Date()).getTime();
var params = {wmode: "transparent", src: "http://www.mywebsite.com/sites/default/files/medias/map/monde.swf?" + _time};
var flashvars = {site: "/fr"};
swfobject.embedSWF("http://www.mywebsite.com/sites/default/files/medias/map/monde.swf?" + _time, "flashContent", 920, 450, "10", false, flashvars, params);
};
// ]]>
</script>
<div id="flashContent"> </div>
The only way to get the buttons back is to edit the source in Firebug, change the SWF URL with something random and change it back so the URL is loaded again (it's not working on the first try, I have to do it few times before it works).
I don't have any cache on the SWF and on the XML I'm calling from AS3, so I don't understand how I can have such a random behaviour :
Here is the relevant parts of the AS3 script :
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var site:String = "";
if (this.loaderInfo.parameters.site != undefined)
site = this.loaderInfo.parameters.site;
_uLoader = new URLLoader();
_uLoader.addEventListener(Event.COMPLETE, _initMap);
var httpHeader : URLRequestHeader = new URLRequestHeader("pragma", "no-cache");
var httpRequest : URLRequest = new URLRequest(site+"/ajax/mywebsite_tools/list_master");
httpRequest.requestHeaders.push(httpHeader);
httpRequest.method = URLRequestMethod.GET;
httpRequest.data = new URLVariables("time="+Number(new Date().getTime()));
_uLoader.load(httpRequest);
_supportContinent = new MovieClip();
this.addChild(_supportContinent);
}
private function _initMap(e:Event):void
{
var cs:mywebsiteSingleton = mywebsiteSingleton.getInstance();
var xml:XML = new XML(_uLoader.data);
cs.xml = xml;
btRetour.buttonMode = true;
btRetour.mouseChildren = false;
btRetour.txt.text = xml.retour.text();
btRetour.gotoAndStop('OUT');
addEventListener(mywebsiteEvent.CONTINENT_CLICK, _contientClick);
btRetour.addEventListener(MouseEvent.CLICK, _retourMonde);
btRetour.addEventListener(MouseEvent.ROLL_OVER, _over);
btRetour.addEventListener(MouseEvent.ROLL_OUT, _out);
}
Figured it out. It was rather trivial in fact, the _initMap() function was randomly called before or after my buttons appear on the timeline. So if i get the xml too fast, the _initMap() function try to refer to a button that doesn't exist.
Fixed it with something a bit dirty, but anyway it works :
private function _initMap(e:Event):void
{
if(!btRetour || btRetour == null || !btRetour.hasOwnProperty("buttonMode")) {
setTimeout(_initMap, 500, e);
return;
}
// ...
}

Multiple HTML5 desktop notifications not displaying

In Chrome, things work OK (multiple notifications display at the same time). But in Firefox when there are multiple notifications NONE get displayed. Please see fiddle for a demo:
http://jsfiddle.net/e6ps2/3/
Scenario: I have a loop that reads through an array of things to be displayed as notifications.
I started off using Notify.js a nice javascript wrapper to the notifications api. And I thought the problem may be related to that. Then I tried using the api directly and the problem persisted.
So I would like to layer the notifications on top of each other if possible (which is how it should happen - and does happen in Chrome). But a possible fallback is to queue the notifications and using notify.js notifyClose() callback function to open the next notification in the queue - but have no idea how to do this.
if (Notify.isSupported()) {
//Notify wrapper Notifications
if (Notify.needsPermission()) Notify.requestPermission();
//var j = 1; //uncomment this for single notification
var j = 2;
for (var i=0;i<j;i++) {
var my_notification = new Notify('Hello World ' + i, {
body: 'Some message here ' + i,
tag: "notify_" + i
});
//uncomment below to show the notify plugin html5 notifications and then comment out the bare bones one
//my_notification.show();
//HTML5 bare nones Notifications
var notification = new Notification("Hi there! " + i, {
body: 'Some message here ' + i,
tag: "Hello_"+ i
});
}
} else {alert("not supported"); }
Hope this all makes sense.
Thanks
For first issue... If permission hasn't been given, you need to give a callback to fire when requesting permission. Moving the send code into a function, allow it to be called standalone, or as the callback
if (Notify.needsPermission()) {
Notify.requestPermission(queueNotifications);
} else {
queueNotifications();
}
Regarding the queueing... I've had a similar issue and Firefox's implementation is poor compared to Chromes. Nevertheless, notifications can be queued using the following method:
create timeinterval variable
using the Notification onshow event, set a timeout with the interval to hide the notification
move the sending of the notification into a separate function that can be called by a timeout inside of the for loop
if (Notify.isSupported()) {
var
showTimeout,
displayTime = 5000,
queueNotifications = function(){
var i,
j = 3;
for (i=0;i<j;i++) {
setTimeout(sendNotifications, displayTime*i, i);
}
},
sendNotifications = function(i){
var
hideTimeout,
onShow = function(){
var $this = this;
hideTimeout = setTimeout(function(){
$this.close();
}, displayTime);
},
my_notification = new Notify('Hello World ' + i, {
body: 'Some message here ' + i,
tag: "notify_" + i
});
my_notification.onShowNotification = onShow;
my_notification.show();
}
if (Notify.needsPermission()) {
Notify.requestPermission(queueNotifications);
} else {
queueNotifications();
}
I've updated your jsfiddle with the working version.
http://jsfiddle.net/e6ps2/5/
Cheers,
Dan
If you set the option 'requireInteraction: true' it will stack your notifications for you, they will not disappear automatically as default but you can use the following to hide them.
setTimeout(notification.close.bind(notification), 5000);

Can I use javascript timer in a mobile browser

I am using IE in a mobile browser. I add a javascript function to a button that when the User clicks it says 'hello'.
This works.
I then add a timer.
On a desktop browser it works.
it does not work on my mobile browser.
This is my code. (note I Had just tried placing an alert('hi'); in the swapImages() and that did not work either.
var div = document.getElementById('divImage');
var imgCached = document.getElementById('imgCached');
document.execCommand("BackgroundImageCache", false, true);
function OnImgLoaded() {
img1.src = imgCached.src;
}
var interval = 30;
var _timer;
var _index = 0;
function test() {
_timer = setInterval('swapImages()', interval);
}
function swapImages() {
imgCached.onload = OnImgLoaded();
imgCached.src = 'my server url~/' + '0000' + _index + '.jpg';
_index = _index + 1;
if (_index == 10) {
_index = 0;
clearTimeout(_timer);
}
}
UPDATE!!
I had been runningit on Chrome desktop and not IE. I am mow testing it in IE desktop. I get the same erro so now I can debug.
The error is this line:
img1.src = imgCached.src;
It tells me:
Unable to get property 'src' of undefined or null reference
I have changed the code to:
var imgLive = document.getElementById('imgLive'); (I have renamed the img control)
function OnImgLoaded() {
imgLive.src = imgCached.src;
}
I get the same error.
I look in Source and the control is correctly named..
Thanks
i'm not sure that the following line is valid in your mobile phone:
imgCached.src = 'http://127.0.0.1/Cloud/test/' ...
the timer executes successfully, but the image doesn't get the proper src since the device doesn't run a web server on it (unless you configured one).
and to answer your topic question, yes- you can use javascript timers in mobile browsers just like desktop browsers.
hope that helped.
First of all: Do you ever call the test function, that starts the timer?
Second: Maybe it's really document.execCommand("BackgroundImageCache", false, true), that fails - it may not be enabled in the mobile version of IE that you are using. You can check if it's enabled using the queryCommandEnabled function, see more here: http://msdn.microsoft.com/en-us/library/ie/ms536676(v=vs.85).aspx

How do I use page name as textbox value

There's a couple of things I'm trying to achieve with Javascript. I'm a bit of a noob, so bear with me.
Firstly I'm using this code to create a popup window:
HTML:
<img src="request.jpg"/>
JS:
var sPage;
function newPopup(url) {
popupWindow = window.open(
url,'popUpWindow','height=400,width=800,left=10,top=10,resizable=no,scrollbars=no,toolbar=no,menubar=no,location=no,directories=no,status=no');
var sPath=window.location.pathname;
var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
window.name = sPage;
}
This part works fine, but what I'm then trying to do is take the current page name and put it into the value of a textbox in 'contact.html'.
This is the code I'm using on the popup page to try and do that:
function add(text){
var TheTextBox = document.getElementById("prodcode");
TheTextBox.value = TheTextBox.value + window.name;
}
This seems to work when it's a normal page I'm linking to, but it wont work if it's a popup. I also can't figure out how to get rid of the extension from the page name.
I realise there are probably a million better ways to do this, but this is the one that seems to make most sense to me. I've looked at cookies, but I can't seem to figure them out.
I know I'm asking a lot, but any help would be greatly appreciated.
Thanks.
If I'm understanding the question right, you could pass the window name as a query param in the URL you're passing to your newPopup function, then grab it in the contact.html page to put it into the box.
For example, your newPopup function could add the query parameter to the url like so:
function newPopup(url) {
var sPath=window.location.pathname;
var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
var windowName = sPage.split(".")[0];
popupWindow = window.open(url + '?window_name=' + windowName,'popUpWindow','height=400,width=800,left=10,top=10,resizable=no,scrollbars=no,toolbar=no,menubar=no,location=no,directories=no,status=no');
window.name = windowName;
}
Then, in your contact.html file, grab the query param when setting the value of your text box, using this sort of logic:
function parseURLParams(name, locat) {
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(locat);
if (results) {
return results[1] || "";
} else {
return "";
}
}
function add(text) {
var TheTextBox = document.getElementById("prodcode");
TheTextBox.value = TheTextBox.value + parseURLParams("window_name", window.location.href);
}
Hope it helps!

How to switch to generic auto redirect with delay

I've inherited a site that calls a javascript on every page to prepend every external link with a link to an exit page. On exit.html, a function in the same script (confirmExit) extracts the original intended url, and that’s served up as a link on the page by ID (<p>Continue to:</p>)
Now, instead of the user having to click on exitLink, an automatic redirect with a delay is wanted. Something like "You will now be taken to exitLink in 10 seconds …"
I’ve seen the setTimeout approach, the <META HTTP-EQUIV="refresh" CONTENT="seconds;URL=the-other-url"> approach, and even a form approach for achieving automatic redirects. Problem is, those seem intended for hard-coded, page-specific redirects. I haven’t been able to figure out how to adapt any of these to the js or the exit.html page to make them work. Sorry, I'm still low enough on the javascript learning curve that I can't seem to find the forest for the trees!
Any solution would be greatly appreciated! (Except php - I can't use that)
Here’s the javascript:
window.onload = function() {
wrapExitLinks();
}
function wrapExitLinks() {
var whiteList = "^gov^mil^";
var exitURL = document.location.protocol + "//" + document.location.host + "/exit.html"; // Default exit is /exit.html from referring site
var currentBaseURL = document.location.protocol + "//" + document.location.hostname + document.location.pathname;
var links = document.getElementsByTagName("a");
var linkDest;
var linkTLD;
var govTLD;
/* Do not wrap links on intersitial exit page */
if (currentBaseURL != exitURL) {
for (var i in links) {
if (links[i].host) {
linkTLD = links[i].hostname.substr(links[i].hostname.lastIndexOf(".") + 1); // Extract top level domain from target link
linkDest = links[i].href;
if (whiteList.indexOf("^" + linkTLD + "^") == -1) {
linkDest = exitURL + "?url=" + encodeURIComponent(linkDest);
links[i].href = linkDest;
}
}
}
} else {
confirmExit();
}
}
function confirmExit() {
var queryString = decodeURIComponent(document.location.search.substr(1));
var linkDest = queryString.substr(queryString.indexOf("url=") + 4);
var exitLink = document.getElementById("exitLink");
/* Assume http:// if no protocol provided */
if (linkDest.indexOf("://") == -1) {
linkDest = "http://" + linkDest;
}
exitLink.href = linkDest;
exitLink.innerHTML = linkDest;
}
The basic script you need is simply:
setTimeout(function () { window.location = 'http://example.com'; }, 10000);
That's all. Work it into your script somewhere.

Categories

Resources