#Angularでいい感じにfaviconを操作するお話。
faviconとは。
favicon(ファビコン)は、ウェブサイトのシンボルマーク・イメージとして、ウェブサイト運営者がウェブサイトやウェブページに配置するアイコンの俗称である。favorite icon(フェイバリット・アイコン:お気に入りアイコン)という英語の語句を縮約したものである。(wikipediaより)
faviconってめんどくさいねん。
今の時代apple-touch-iconとかなんとかいっぱいあるし。。。
svgを使えるようになったらええんやけど、今んところサポートしてるんはFirefoxだけ。 → http://caniuse.com/#feat=link-icon-svg
##余談
favicon一括生成サイトというものがあるそうで → http://realfavicongenerator.net/
こいつはfaviconはもちろん、iPhoneやandroid、windows8とかとかいい感じに一括生成してくれる超便利サイト。
##序論
余談はさておき、今回はangularでfaviconをいい感じに操作するお話をします。
その名も favico.js → http://lab.ejci.net/favico.js/
faviconにバッチをつけたり、アニメーションさせたり、入れ替えたり、音量バッチとかとか。
webcamでインカメの動画をfaviconで再生したり(←何に使うねん)
↓↓↓
Works on Chrome, Firefox, Opera and IE11+ らしい。
僕はチャットツールを作ろうとしてて、未読の数を出すのにいいのないかなって思ってたら、favicon.jsを耳に挟んだので触ってみたことを書いていく。
##導入
メッセージの未読を検出する方法については以下に書きましたので、これを読んでください。
http://qiita.com/shinsukeimai/items/dd1e96456b7b51e32cce
ここでのスクリブトを元に書いていきます。
###初期状態
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="app.css">
</head>
<body>
<div ng-app="myApp">
<div ng-controller="MainCtrl as main">
<ul ng-repeat="message in main.messages">
<li msg content=message ng-class="{message: message.read }">{{message.text}}</li>
</ul>
</div>
</div>
<script src="./angular.min.js"></script>
<script src="./favico.js"></script>
<script src="app.js"></script>
</body>
"use strict";
angular.module("myApp", []);
angular.module("myApp").directive("msg", ["$window", function($window){
return {
restrict: "A",
scope: {
content: "="
},
link: function(scope, element){
angular.element($window).bind('scroll', function () {
var elementY = element[0].offsetTop;
var pageTop = this.pageYOffset;
var pageBottom = this.pageYOffset + this.innerHeight - 50;
if(elementY > pageTop && elementY < pageBottom){
scope.content.read = true;
scope.$apply();
}
});
}
}
}]);
angular.module("myApp").controller("MainCtrl", function(){
this.messages = [];
for(var i = 0; i < 100; i++){
this.messages[i] = {
text: "message" + i,
read: false
}
}
});
.message{
color: red;
}
ここからスタートしていきます。
##環境
- faviconを用意します。
- angularを用意します。
- favico.jsを用意します。(githubから落として下さい。)
##実装
index.htmlを書いていきます。
linkにfaviconを設定します。
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<!-- ここ!!!-->
<link rel="shortcut icon" href="favicon32.ico">
<link rel="stylesheet" href="app.css">
</head>
<body>
<div ng-app="myApp">
<div ng-controller="MainCtrl">
<ul ng-repeat="message in messages">
<li msg content=message ng-class="{message: message.read }">{{message.text}}</li>
</ul>
</div>
</div>
<script src="./angular.min.js"></script>
<script src="./favico.js"></script>
<script src="app.js"></script>
</body>
favico.js用にService(factory)を書いていきます。
詳しい動きを設定したい時はhttp://lab.ejci.net/favico.js/
angular.module("myApp").factory("faviconService", function(){
var favicon = new Favico({
//animationを切る
animation: "none"
});
var badge = function(num){
favicon.badge(num);
};
return {
badge: badge
};
});
controllerを書き足します。
スクロールした時にfaviconのbadgeの値を変えていきます。
angular.module("myApp").controller("MainCtrl", ["$scope", "$window", "$timeout", "faviconService", function($scope, $window, $timeout, faviconService){
//初期値設定
var num, scrollTimer;
scrollTimer = false;
$scope.messages = [];
for(var i = 0; i < 100; i++){
$scope.messages[i] = {
text: "message" + i,
read: false
}
}
num = $scope.messages.length;
faviconService.badge(num);
//スクロール時の動き
angular.element($window).bind('scroll', function () {
//スクロール中の時の動きで100msの間を空けます。
if(scrollTimer){
$timeout.cancel(scrollTimer);
}
scrollTimer = $timeout(function(){
var newNum = 0;
//メッセージの既読を確認します。
$scope.messages.forEach(function(message){
if(!message.read){newNum++; }
});
if(num !== newNum){
faviconService.badge(newNum);
num = newNum;
}
},100);
});
}]);
まとめますと。
"use strict";
angular.module("myApp", []);
angular.module("myApp").directive("msg", ["$window", function($window){
return {
restrict: "A",
scope: {
content: "="
},
link: function(scope, element){
angular.element($window).bind('scroll', function () {
var elementY = element[0].offsetTop;
var pageTop = this.pageYOffset;
var pageBottom = this.pageYOffset + this.innerHeight - 30;
if(elementY > pageTop && elementY < pageBottom){
scope.content.read = true;
scope.$apply();
}
});
}
}
}]);
angular.module("myApp").controller("MainCtrl", ["$scope", "$window", "$timeout", "faviconService", function($scope, $window, $timeout, faviconService){
//初期値設定
var num, scrollTimer;
scrollTimer = false;
$scope.messages = [];
for(var i = 0; i < 100; i++){
$scope.messages[i] = {
text: "message" + i,
read: false
}
}
num = $scope.messages.length;
faviconService.badge(num);
//スクロール時の動き
angular.element($window).bind('scroll', function () {
//スクロール中の時の動きで100msの間を空けます。
if(scrollTimer){
$timeout.cancel(scrollTimer);
}
scrollTimer = $timeout(function(){
var newNum = 0;
$scope.messages.forEach(function(message){
if(!message.read){newNum++; }
});
if(num !== newNum){
faviconService.badge(newNum);
num = newNum;
}
},100);
});
}]);
angular.module("myApp").factory("faviconService", function(){
var favicon = new Favico({
animation: "none"
});
var badge = function(num){
favicon.badge(num);
};
return {
badge: badge
};
});
こんな感じです。
##結果
###初期状態
##感想
そんなにangularって感じでもなかったかな。
同じことしたい人には参考になるかも。
これ、ページを開いておくと、ブックマークバーにあるアイコンにもこのbadgeが現れて、増減を出してくれる。
おもろ
お試しアレ。