Tuesday 6 August 2013

Dynamic favicon

I saw a post the other day, that Google had changed the favicon to display a play symbol when audio is playing in that tab/window, therefore I decided to see if I could knock up a page that dynamically changes the favicon.

My idea was to create icons that would count to 10 just so it would be easy to tell when it is working correctly. Therefore I created 16x16 pixel png images containing my numbers 1-10 called favicon1.png - favicon10.png. I also created a start image called favicon0.png this is the same image as posted on the banner of my blog (one of the fractal images I created).

To add a favicon is easy just add the following to your html in the head section

<link id="favicon" rel="shortcut icon" type="image/png" href="location of your image">

To change this dynamically it should be easy create a loop where the loop counter goes from 0 to 10 and modify the href in this line.
First problem, how to modify this line. I gave the link an id so I should be able to reference this via the DOM. This can be referenced using the following piece of javascript

document.getElementById('favicon');

Now I just need to create a loop in javascript and modify the href, but wait there is a problem with this. To display each individual favicon image I need my script to pause for a short amount of time. In other languages we would just pause by calling some kind of sleep or wait function, however as this will be running in a browser we do not want it too sleep as this would impact the loading of the page. It also turns out that there is no sleep function in javascript for precisely this reason.
So how to achieve a pause to display the images. Looking around, there are some Timing Events that can be used in javascript, the one that looked to fit the bill is setInterval.
To use this I had to modify the way I was writing the script, rather than having a loop and pausing within the loop, I created a function that I would call at a particular interval.

I also had to remove the old favicon link before adding a new one.

The following sample code is what I came up with and seems to do what I was after, note I was testing on my local machine so the href entries all point to local files.


function changefav(i) {
   //only have 10 numbers to display
   if (i==11) {
         //remove Timeout
        clearTimeout(changeInterval);
        return;
   }
   var filename = "file:///tmp/favicon" + i +".png";
   myfav=document.getElementById('favicon');
   header.removeChild(myfav);
   lnk.href=filename;
   header.appendChild(lnk);
}

header=document.getElementsByTagName("head")[0];
//create new link element, only href will change
var lnk=document.createElement('link');
lnk.id="favicon";
lnk.type="image/png";
lnk.rel="shortcut icon";

var i=0;

//call changefav function every 100 milliseconds
changeInterval=setInterval('changefav(i++)', 100);



I placed this into a simple html document and added a favicon link as mentioned above.

This worked well in firefox.

Instead of creating separate images I could have taken a base image and then modified it using a canvas element dynamically in javascript.

While researching favicons I found Defender of the Favicon, a Defender clone implemented as dynamic favicons.