favicon

Small  JavaScript function to make it easy to render web page lists with favicons like this:

  jQuery home page

  Wikipedia page on favicons

  my academic home page

This is using the favicon for each site.  Rather than adding each image separately, a default image is initially included and the JavaScript substitutes the favicon if it exists.

See the live example page, which is small so easy to view source from1.

The HTML code to produce the above simply adds a class “favicon-fetch” to each image, and wraps each one in a link to the relevant site.

<a href="http://jquery.com/"><img class="favicon-fetch" style="border: 0;" src="unknown-favicon.png" alt="" width="16" /></a>
       <a href="http://jquery.com/">jQuery homepage</a>

Note “unknown-favicon.png” is a default image.  Any image can be used, it could be an invisible image, or something generic such as an image of a page.

Alternatively a special attribute “favicon-site” can be added to the <img> tag.

<img src="unknown-favicon.png" favicon-site="http://en.wikipedia.org/wiki/Favicon" width="16" />

Once the page has loaded,  favicon.js scans for these marked images, finds the favicon for each site and substitutes it. The fetching of the favicons is done asynchronously after the page has loaded, so does not slow down your page loading, and if a favicon is not found, it simply leaves the original default image.

For a small list like the above, this is a bit like overkill (simply locate the images by hand!), although dynamically accessing the images means they update when the site updates its favicon.  It is really most useful for automatically created lists, where it reduces server-side complexity and latency due time it would take to check for the icons during page delivery.

Note that this only checks for the default favicon.ico at the site root.  Some web pages specify a shortcut icon using a <link> tag in the page header. The JavaScript “same origin policy” makes it hard to access these dynamically without going through an AJAX server script.

In summary, the HTML to produce the above looks like:

...
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://www.alandix.com/code/favicon/favicon.js"></script>
...
<a href="http://jquery.com/"><img class="favicon-fetch" style="border: 0;" src="unknown-favicon.png" alt="" width="16" /></a>
       <a href="http://jquery.com/">jQuery homepage</a>
<br />
<img src="unknown-favicon.png" favicon-site="http://en.wikipedia.org/wiki/Favicon" width="16" />
      <a href="http://en.wikipedia.org/wiki/Favicon">Wikipedia page on favicons</a>
<br />
<a href="http://www.alandix.com/"><img class="favicon-fetch" style="border: 0;" src="unknown-favicon.png" alt="" width="16" /></a>
       <a href="http://www.alandix.com/academic/">my academic home page</a>
...
<script type="text/javascript" language="javascript">
    loadFavicons(document);  // either at the end of the page body or in onload handler
</script>

The full JavaScript function is below at alandix.com/code/favicon/favicon.js.  It uses jQuery.find() to locate all the images with the relevant class, then looks for either the special ‘favicon-site’ attribute (first) or an immediately containing anchor tag.  If neither is found the image is silently ignored.  If a suitable web site is found, the default favicon location is checked at the site root by using a JavaScript image object.  Only if this succeeds is the actual image tag updated (by which point the image will also have been preloaded).

function loadFavicons(root) {
    $(root).find("img.favicon-fetch").each( function(index) {
        var site = $(this).attr('favicon-site');
        if ( ! site ) {
            site = $(this).parent().filter('a').attr('href');
        }
        if ( !site ) {
            return;
        }
        var match = site.match(  /(http(s)?://([^/]+)/)/  );
        if ( ! match ) {
            return;
        }
        domain = match[1];
        var favicon = domain + 'favicon.ico';
        var target = this;
        var image = new Image();
        image.onload = function() {
            $(target).attr('src',favicon);
        }
        image.src = favicon;
    });
}
  1. This blog page is actually using fixed images.  I may get round to doing a WordPress plugin, just needs to include the relevant Javascript files and shortcode …[back]