Favicons should ideally be easy to manipulate, as easy as manipulating the web page's UI. (Favicons are the little website icons you see in the address bar, browser tabs, etc.) For example, a chat app like Meebo could signal that your buddy's trying to contact you, a mail app like GMail could indicate You Have Mail!
I've found surprisingly little info on this - is anyone doing it? Anyway, I've been wanting to play around with this for a while and having recently submitted the final book draft (post pending), I finally had some spare time to play with it. Fortunately, it turns out to be perfectly feasible - it seems that Firefox and Opera both use <link> tags to determine favico, and this can be changed dynamically to satisfaction. The only gotcha is that you can't try to be too efficient - if you reuse an existing link object and overwrite its href property, the browsers won't pay any attention. so you simply have to remove the existing link tag and add back a new one with the new icon URL. Unfortunately, IE and Safari don't seem to use the link technique at all - I think they just use the "favicon.ico" file. If you know of a way their icons could be dynamically manipulated, please mail me or add a comment here.
So I've created a library, favicon.js, that lets you manipulate favicons with a single call - changeFavicon("theIconUrl.ico");. You can also set the document title, changeFavicon("theIconUrl.ico", "Hi Everybody!"), which just sets document.title. There are a couple of demos and a brief FAQ:
- Type a letter, see the icon change.
- The icons cycle automatically, using a timer. So you can stick it in a background tab and see how it looks.
- FAQ
Implementation Details. Here's the favicon.js code as it stands, all 32 lines of it :-).
- var favicon = {
- change: function(iconURL) {
- if (arguments.length==2) {
- document.title = optionalDocTitle;
- }
- this.addLink(iconURL, "icon");
- this.addLink(iconURL, "shortcut icon");
- },
- addLink: function(iconURL, relValue) {
- var link = document.createElement("link");
- link.type = "image/x-icon";
- link.rel = relValue;
- link.href = iconURL;
- this.removeLinkIfExists(relValue);
- this.docHead.appendChild(link);
- },
- removeLinkIfExists: function(relValue) {
- var links = this.docHead.getElementsByTagName("link");
- for (var i=0; i<links .length; i++) {
- var link = links[i];
- if (link.type=="image/x-icon" && link.rel==relValue) {
- this.docHead.removeChild(link);
- return; // Assuming only one match at most.
- }
- }
- },
- docHead:document.getElementsByTagName("head")[0]
- }
Update (Two Days Later)
Crikey! Dugg and on Delicious Popular. And, well, Ajaxian too ;-). Digg is interesting ... The last time I submitted my own story to digg, it got precisely two diggs (thanks to the other guy!). This time, I didn't bother. Is there a moral here?
New, improved, with animate(). Most people get dynamic favicons, but some people have said this whole thing is about animation, about as useful as a blink tag, etc. Okay, that kind of misses the main point, which is about notifying the user while a tab is in the background. The FAQ makes it pretty clear that animated icons was a kind of afterthought (actually, it only occurred to me after I created the cycling demo - changing according to a timer was simply the easiest way to update a background tab, since there's no chat functionality needed or anything like that). But, you know, when a simple idea like that causes seems so wrong to some people, there's probably wheels in it. And while I did say animated GIFs are possibly more elegant in the FAQ, it since occurred to me that it's a bit of a hassle for the casual developer to make an animated GIF. You also get the benefit of compatibility with Opera (and maybe others?). So I've added an animate() method, only 8 more lines in all, that lets you cycle through a sequence of images. I expect to post it over the weekend. Mmm...Eye Candy!

26 responses so far ↓
1 Timothy Hatcher // Mar 17, 2006 at 5:21 pm
Safari does support
2 Timothy Hatcher // Mar 17, 2006 at 5:22 pm
Sorry, Safari does support LINK REL=”icon”, just not dynamically.
3 Erik // Mar 17, 2006 at 5:26 pm
It should be:
change: function(iconURL, optionalDocTitle) {
in the above code.
4 Erik // Mar 17, 2006 at 5:30 pm
It should be:
>change: function(iconURL, optionalDocTitle) {
in the above code.
5 Jon // Mar 17, 2006 at 7:18 pm
I believe this scenario is possible:
When an event is fired or procedure is done on the server, a new procedure will get called and create a new Favicon in the wwwroot and flush the page, that the user is currently on, to the client. This will make the page reload and “voila” new Favicon. But you need to remain some kind of viewstate so the user don’t just gets handed a new page with all hers interactions gone (like typing etc.). And most importantly the Favicon is the same for all users.
Come to think of it, I don’t think there is any bearable solution.
6 Johan Sundström // Mar 17, 2006 at 7:36 pm
I’ve been using the technique for a while to add favicons to those of my more frequently visited sites that don’t provide their own (by way of client side Greasemonkey scripts).
I just centralized those little scripts into my Mark my links tool, which relieves me of the hassle of writing a new script every once in a while.
Thanks for pointing out that one needs to drop link tags already in place to do real overrides though; I wasn’t aware of that, as I have mostly been adding to sites sans icons until now.
7 Samurai // Mar 17, 2006 at 7:47 pm
Thanks for posting this. It will come in handy for my site/podcast.
8 Matthias 'moeffju' Bauer // Mar 17, 2006 at 7:49 pm
Neat. Can’t say I ever needed it, but that should not hold anyone back
Minor nit: You don’t need to addLink both “
icon” and “shortcut icon” - rel takes a list of values, separated by space, so “shortcut icon” actually means the tokens “shortcut” and “icon” - it’s a superset of “icon“.9 Kruncher // Mar 18, 2006 at 2:14 am
With 56K there is a half a second delay before the image is switched, which if you are trying to make it animated; looks REALLY crappy.
Maybe you could preload the images before changing it.
10 mahemoff // Mar 18, 2006 at 2:42 am
Erik,
The arguments.length takes care of it, it’s I think the most easiest way to do overloading in JS. You could also have the arg though as you say and check if it’s defined.
Jon, It’s true you can change favicon on the server-side - if the JS did something like submit a form or change the document URL, it would force a page refresh and at that point the server could overwrite favicon.ico. In practice, I’m not convinced it would add anything, though, because apparently Safari and IE cache favicon.ico without shame. I’m still learning about all the subtleties from everyone, but that’s my perception right now.
Johan, I probably made a bit of a deal about the dropping and re-adding in case it helped anyone, though most people will probably do that anyway. For instance, with On-Demand Javascript, I’ve never even tried to overwrite a script node’s source - I’ve only ever deleted and added.
Matthias, Sweet tip. Assuming it works fine on Opera and FF, it will neaten up the code nicely.
11 Ivan Minic // Mar 18, 2006 at 8:57 am
Hehe.. good stuff!
12 Favicon dinamiche con AJAX e Javascript at Vortexmind: free your mind // Mar 18, 2006 at 1:19 pm
[…] In ogni caso, ci ha pensato Michael Mahemoff: nel suo articolo viene spiegato come fare, e potete scaricare una libreria javascript pronta per l’uso con tutte le API adatte allo scopo. Buon divertimento! Technorati Tags: accessibility, ajax, design, dinamica, dynamic, favicon, javascript, library, tutorial, web, webdesign Bookmark this to: […]
13 Jason // Mar 18, 2006 at 2:33 pm
The question begs to be asked… why doesn’t this site have a favicon?
14 Michael Mahemoff // Mar 18, 2006 at 3:30 pm
Jason,
There was a favicon until about 12 hours before I posted this, when I upgraded Wordpress. It’s back now. (I have favicons in a similar theme for all my sites).
15 Alvanweb » Favicon های دینامیک // Mar 19, 2006 at 6:56 am
[…] تصورش عجیب است که حتی Favicon صفحات شما حالت دینامیک و پویا داشته باشد. فکر کنم اولین باری است که مطلبی مانند این درباره ایجاد Favicons آن هم به صورت پویا بر روی وب منتشر می شود. تنها مشکل، عدم پشتیبانی کامل مرورگری مثل IE از این خاصیت است. مرورگرهایی نظیر فایرفاکس و اپرا از بر چسپ link برای تعیین Favicon استفاده می کنند در حالی که IE و Safari از این الگو برای تشخیص Favicon بی بهره اند. […]
16 marksdigital // Mar 20, 2006 at 1:47 pm
Dynamic Favicons…
Here’s a cool little trick, you can change the favicon for your page after it is loaded, using javascript. From Software As She’s Developed - Dynamic Favicons:
So I’ve created a library, favicon.js, that lets you manipulate favicons with…
17 Favicons dinámicos » Celi Online // Mar 22, 2006 at 9:30 pm
[…] Traducción de Software As She’s Developed […]
18 mohameed // Aug 7, 2006 at 12:51 pm
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
19 Honorable Mention » Blog Archive » Random favicon.ico // Oct 20, 2006 at 10:43 am
[…] The above JavaScript does seem to mirror the PHP method. There is more than one way of going about doing this with JavaScript, but also, JavaScript can take this a step further and dynamically change the favicon every few seconds or minutes if you want. You could take the “Ajax” approach as detailed here, or you can use CSS and then use JavaScript to manipulate it! First you’ll need to add a id property to your favicon link: […]
20 Faviconlar: Üreteçleri, Tasarımı, Yapımı | BlogcuBlogu.com // Nov 28, 2007 at 8:25 pm
[…] Son zamanlarda sitelerde animasyonlu faviconlar görünmeye başladı. Bunu yapmanın birkaç yolunu bulabildim. JavaScript ile yapmak için burayı, Photoshop için de burayı inceleyebilirsiniz. Ayrıca bir de burası var. Photoshop‘tan bahsetmişken ico formatında dosyalar elde etmek için şuradaki eklentiyi kullanabilirsiniz. Yine Photoshop ile ilgili şurada da bilgi mevcut. […]
21 Skylog » Blog Archive » links for 2008-02-05 // Feb 5, 2008 at 6:18 am
[…] Dynamic Favicons (tags: javascript) […]
22 Talk To Frank - dynamic favicon | Only Network // Feb 17, 2008 at 4:14 pm
[…] of a page. Reading about it, it turns out you can change your favicon dynamically use AJAX (see here). However, what they were using was an even simpler technique. Apparently if you rename an animated […]
23 Software As She’s Developed » Blog Archive » Taking Browser Tabs Seriously // Feb 23, 2008 at 6:50 pm
[…] just updated my favicon library, which I first wrote about here. I’ll explain more about the update in a separate post. For now, I want to talk about browser […]
24 Amyobus Key // Jun 23, 2008 at 2:25 pm
Here, at Cathetel, we use a simple IF argument in the Head Section that allows us to direct our static favicon to Internet Explorer, and all others to display, if they are able to, the animated version. Netscape and Firefox show the animated favicon. Directions for doing this, if anyone is interested, is at http://www.cathetel.com/favicon.htm . We must study your coding though as it is more sophisticated.
25 mahemoff // Jun 23, 2008 at 4:13 pm
Amyobus, what you’re using is a single animated GIF file, which is fine for most purposes. This article is about programmatically changing the favicon. You can use it for a straightforward animation, but since you could already do that in the way you’ve done it, the main reason to use this library is to change the icon when an event occurs.
26 Design favicons For Your Site With Favicon Generators | Solid Blogger // Dec 9, 2008 at 12:28 am
[…] Make animated favicon with java animated favicon maker […]
Leave a Comment