前回は、
追加機能の概要
多くのWebアプリでは、
例えばOdometerが目的地までの距離を通知する間隔は、
設定画面の呼び出しには、


Webアプリの構成
Webアプリを構成するファイルにoptions.

{
"name": "Odometer",
"description": "距離計",
"version": "0.3",
"app": {
"launch": {
"local_path": "main.html"
}
},
"icons": {
"16": "icon_16.png",
"48": "icon_48.png",
"128": "icon_128.png"
},
"options_page": "options.html",
"background_page": "background.html",
"permissions": [
"geolocation",
"notifications",
"background"
]
}
"options_
Options Page
Options Pageは、


Odometerの設定画面として、
- デスクトップへの通知の有効/
無効 - 通知時間
(秒) - 目的地~1km圏内、
1km~10km圏内、 10km圏外でのそれぞれの通知間隔 (mまたはkmで指定)
今回は利用しませんが、

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Odometer設定</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/options.css">
<script src="js/options.js"></script>
</head>
<body>
<header>
<h1>Odometer設定</h1>
</header>
<section>
<h2>通知設定</h2>
<div class="internal">
<div class="setting">
<p>
<label for="notify-setting">デスクトップへ通知: </label>
<input type="checkbox" id="notify-setting" checked>
</p>
<p>
<label for="display-time">通知時間:</label>
<input type="number" min="0" step="1" value="5" id="display-time"> 秒
<span class="aside">※ 0秒を指定すると通知は自動的に閉じられません</span>
</p>
</div>
<div class="detail-setting">
<table>
<tr>
<th>通知範囲</th>
<th>通知間隔</th>
</tr>
<tr>
<td>目的地~1km園内</td>
<td>
<input type="number" value="100" min="0.001" step="1" id="short">
<select id="short-unit">
<option value="m" selected>m</option>
<option value="km">km</option>
</select>
ごとに通知する
</td>
</tr>
<tr>
<td>1km~10km圏内</td>
<td>
<input type="number" value="1" min="0.001" step="1" id="middle">
<select id="middle-unit">
<option value="m">m</option>
<option value="km" selected>km</option>
</select>
ごとに通知する
</td>
</tr>
<tr>
<td>10km圏外</td>
<td>
<input type="number" value="5" min="0.001" step="1" id="long">
<select id="long-unit">
<option value="m">m</option>
<option value="km" selected>km</option>
</select>
ごとに通知する
</td>
</tr>
</table>
</div>
</div>
<div class="buttons">
<input type="submit" value="設定" id="apply">
<input type="reset" value="キャンセル" id="cancel">
</div>
</section>
</body>
</html>
Web Storage
Web Storageとは、
データの保存と参照
データの保存と参照には、
// 通知範囲
var ranges = [
'short', // 目的地~1km圏内
'middle', // 1km~10km圏内
'long' // 10km圏外
];
~省略~
// 設定
document.getElementById('apply').addEventListener('click', function(){
// 通知設定/通知時間
var setting = {
notify: document.getElementById('notify-setting').checked,
display: parseInt(document.getElementById('display-time').value, 10)
};
// 通知距離
for ( var i = 0, len = ranges.length; i < len; i++ ) {
var distance = parseFloat(document.getElementById(ranges[i]).value, 10);
if ( document.getElementById(ranges[i] + '-unit').value === 'm' ) {
distance /= 1000;
}
setting[ranges[i]] = distance;
}
localStorage.setItem('setting', JSON.stringify(setting));
}, false);
「設定」
// 初期化
function init(){
var setting = JSON.parse(localStorage.getItem('setting'));
// 通知設定
document.getElementById('notify-setting').checked = setting.notify;
// 通知時間
document.getElementById('display-time').value = setting.display;
// 通知距離
for ( var i = 0, len = ranges.length; i < len; i++ ) {
var distance = setting[ranges[i]];
if ( distance < 1 ) {
document.getElementById(ranges[i] + '-unit').selectedIndex = 0; // 単位:m
document.getElementById(ranges[i]).value = (distance * 1000);
} else {
document.getElementById(ranges[i] + '-unit').selectedIndex = 1; // 単位:km
document.getElementById(ranges[i]).value = distance;
}
}
}
設定画面のイニシャルセットとして、
ここでは、
//データの保存(setItemと同じ意味)
localStorage.setting = JSON.stringfy(setting);
localStorage["setting"] = JSON.stringfy(setting);
//データの参照(getItemと同じ意味)
var setting = JSON.parse(localStorage.setting);
var setting = JSON.parse(localStorage["setting"]);
メソッド/ | 説明 |
---|---|
length | ストレージの長さを返す |
key(n) | n番目のキーを返す |
getItem(key) | キーに対応する値を返す |
setItem(key, value) | キーと値のペアを保存する |
removeItem(key) | キーと対応する値を削除する |
clear() | ストレージを消去する |
設定の反映
実際に設定された値を使って通知を行うように変更します。設定値をキャッシュする方法もありますが、
// デフォルト設定
if ( !localStorage.getItem('setting') ) {
var setting = {
notify: true, // 通知設定
display: 5, // 通知時間(sec)
short: 0.2, // 目的地~1km圏内: 200m
middle: 1, // 1km~10km圏内: 1km
long: 5 // 10km圏外: 5km
};
localStorage.setItem('setting', JSON.stringify(setting));
}
まだ何も設定されていない最初のアクセスの際にデフォルト値を利用するようにします。
/*
* 自動更新を開始する
*/
var watchId = 0; //自動更新停止用のID
function startWatchPosition(sender, sendResponse){
~省略~
// デスクトップに通知
var setting = JSON.parse(localStorage.getItem('setting'));
if ( setting.notify ) {
// 距離によってしきい値を変える
var threshold = 0;
if ( distance < 1 ) {
// 目的地~1km圏内
threshold = setting.short;
} else if (distance < 10 ) {
// 1km~10km圏内
threshold = setting.middle;
} else {
// 10km圏外
threshold = setting.long;
}
// 一度通知した距離は再通知しない
var notifiedKey = Math.floor(distance / threshold) * threshold;
if ( !notified[notifiedKey] ) {
notify('目的地までの距離', '約 ' + distance + ' km', setting.display);
notified[notifiedKey] = true;
}
}
~省略~
}
以前より変更された部分は、
これで、
まとめ
今回は、
- ※
crxファイルはzipファイルですので、
右クリックからのダウンロード後に拡張子をzipに変えていただければ中身を参照できます。Odometerのコード量が増えてきたため、 参考のためのソースコードは上記ファイルより取得してくださるようお願いします。