いろいろなサービスやツールを使っているとたまに見かける、faviconに通知数を表示する実装を試してみました。
サンプルコード
まずは通知数を含んだfaviconを用意して、画像を差し替える方法を試してみます。
以下の画像を用意しました。
デフォルト / 1つ目 / 2つ目 / 3つ目 / 4つ目 / 5つ目
head内にデフォルトの画像でfaviconを設定します。
head
<link rel="icon" type="image/png" href="icon/favicon.png" />
今回はボタンをクリックしたタイミングで通知数を追加する形にしてみます。
HTML
<button id="add">追加</button>
JavaScriptでボタンクリック時にfaviconを差し替えるようにします。
JavaScript
var count = 0;
var max = 5;
document.getElementById('add').addEventListener('click', function() {
if(count < max) {
count++;
var faviconTag = document.querySelector('link[rel="icon"]');
faviconTag.href = 'icon/favicon-' + count + '.png';
}
}, false);
あらかじめ通知数付きのfaviconを用意するのではなく、canvasを使って通知数を追加するようにしてみます。
JavaScript
var count = 0;
document.getElementById('add').addEventListener('click', function() {
count++;
generate_notification_favicon('icon/favicon.png', count);
}, false);
/**
* 通知付きのfaviconを設定する
* @param {number} favicon - 元にするfaviconのパス
* @param {number} num - 通知する数字
*/
function generate_notification_favicon(favicon, num) {
// canvasの準備
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 元にするfaviconの読み込み
var img = new Image();
img.onload = function() {
// canvasに元のfaviconを描画
var w = img.width;
var h = img.height;
canvas.width = w;
canvas.height = h;
ctx.drawImage(img, 0, 0);
// 通知数部分の描画
ctx.fillStyle = '#ff0000';
ctx.fillRect(w*0.4, h*0.4, w*0.6, h*0.6);
ctx.font = 'bold ' + w*0.5 + 'px MS PGothic';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = '#ffffff';
ctx.fillText(num, w*0.7, h*0.7);
// 生成したfaviconを変換して設定
var url = canvas.toDataURL('image/png');
var faviconTag = document.querySelector('link[rel="icon"]');
faviconTag.href = url;
}
img.src = favicon;
}
これでchromeやFirefoxでは問題なく表示できたのですが、IEとedgeでは通知数が表示できませんでした。
canvasで通知数を描画するデモページ
調べていると1度link要素を削除してから追加する必要がある、みたいな情報を見かけたので修正してみます。
JavaScript
var count = 0;
document.getElementById('add').addEventListener('click', function() {
count++;
generate_notification_favicon('icon/favicon.png', count);
}, false);
/**
* 通知付きのfaviconを設定する
* @param {number} favicon - 元にするfaviconのパス
* @param {number} num - 通知する数字
*/
function generate_notification_favicon(favicon, num) {
// canvasの準備
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 元にするfaviconの読み込み
var img = new Image();
img.onload = function() {
// canvasに元のfaviconを描画
var w = img.width;
var h = img.height;
canvas.width = w;
canvas.height = h;
ctx.drawImage(img, 0, 0);
// 通知数部分の描画
ctx.fillStyle = '#ff0000';
ctx.fillRect(w*0.4, h*0.4, w*0.6, h*0.6);
ctx.font = 'bold ' + w*0.5 + 'px MS PGothic';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = '#ffffff';
ctx.fillText(num, w*0.7, h*0.7);
// 現在のfaviconを削除
var currentLink = document.querySelector('link[rel="icon"]');
currentLink.parentNode.removeChild(currentLink);
// 生成したfaviconを変換して設定
var url = canvas.toDataURL('image/png');
var link = document.createElement('link');
link.rel = 'icon';
link.type = 'image/png';
link.href = url;
document.getElementsByTagName('head')[0].appendChild(link);
}
img.src = favicon;
}
この方法でもIEとedgeで通知数が表示されませんでした。
canvasで通知数を描画するデモページデモページ2
試してみた現時点では、IEやedgeへの対応がなくてもよい場合はcanvasを使って、対応が必要な場合はあらかじめ画像を用意するしかなさそうです。
【参考サイト】
- faviconで動的に通知する仕組み – ASnoKaze blog
- faviconに通知数を表示させるやつをjsでやる – Qiita
- サーバからの通知方法にfaviconの動的変更を利用する blog.katsuma.tv
コメントが承認されるまで時間がかかります。