sukechan.net
JavaScript 第 5 版 1、2 章まとめ
- 2008-10-07 (火)
- JavaScript
1 章 JavaScript の概要
特徴
- オブジェクト指向機能を備えたインタプリタ型言語。
- 型付けが弱い。オブジェクトのプロパティに任意の型の値を指定できる。
- オブジェクト指向の継承機能はプロトタイプベース。
2 章 字句構造
2.1 文字コード
- プログラムは 16 ビットの Unicode を使う。
2.2 大文字と小文字
- キーワード、変数、関数名、識別子で大文字と小文字は区別される。
2.6 リテラル
- プログラムに直接記述するデータ値をリテラルという。
- 配列リテラルやオブジェクトリテラルもある。
2.7 識別子
- 変数や関数、ループのラベル等で使用する名前を識別子という。
- 先頭の文字は Unicode 文字、アンダースコア、ドル記号のいずれか。
- その後は Unicode 文字、数字、アンダースコア、ドル記号のいずれか。
- Comments: 0
- Trackbacks: 0
JavaScript 第 5 版(サイ本)を読み始める
- 2008-10-06 (月)
- JavaScript
通称「サイ本」と呼ばれる、JavaScript 第 5 版を買いました。
JavaScript は理解しているようでなかなか奥が深く、プロトタイプベースのところとか理解できてないのでちゃんと理解して実践に活かしたいと思います。
読み進めながら、このブログにまとめを書いて行こうと思ってます。
なにせ分厚い(671 ページもある)ので、内容に応じてメリハリをつけていこうかと。
1部の JavaScript のコアな部分を重点的に進める予定です。
あと、クイックリファレンスも合わせて購入しました。
JavaScript 第5版
村上 列 
JavaScriptクイックリファレンス 第5版―JavaScript1.5対応
木下 哲也 福龍興業 
関連記事
- Comments: 0
- Trackbacks: 0
WordPress 2.6.2 にバージョンアップ
- 2008-09-23 (火)
- WordPress
最近ずっと放置していた、WordPress のバージョンアップをして、2.6.2 にしました。
以前のバージョンから結構バージョンが空いているので、すんなり終わるか心配でしたが、取り越し苦労で済みました。
アップグレードの手順としては、ほぼ下記の記事の通りでした。
sukechan.net - WordPress 2.2.3 ME から 2.3.3 日本語版に移行
それと、WordPress を iPhone/iPod touch に最適化するプラグイン「WPtouch」を入れてみました。こんな感じになりました。

参考リンク
- Comments: 0
- Trackbacks: 0
Google Reader のスターをまとめて開く Greasemonkey
- 2008-09-13 (土)
- JavaScript
これはなに?
Google Reader でスターを付けた記事をまとめて開くことができる Greasemonkey です。
スター付きアイテムなどを開いた状態で、「o」キーを押すとスター付きの記事を最大 5 件開きます。
開いた記事のスターは消えます。
最近 Google Reader を使うようになったんですが、スターを付けた記事をまとめて開くのがめんどくさかったので作りました。
既に下記リンク先に Greasemonkey はあるのですが、getElementsByTagName などが使われていて Safari では使えなかったので動くようにしました。もちろん Firefox でも動きます。
Google Reader のスターを Livedoor Reader のピンみたいにまとめて開く Greasemonkey - もうゴールしていいブログ
インストール
こちらからインストールしてください。
Google Reader Star Opener – Userscripts.org
ソース
// ==UserScript==
// @name Google Reader Star Opener
// @namespace http://www.sukechan.net/
// @description Starred item open in a lump for Google Reader.
// @include http://www.google.co.jp/reader/view/*
// @include http://www.google.com/reader/view/*
// @version 1.0.1
// ==/UserScript==
(function() {
var MAX_WINDOW_OPEN = 5;
var onKeyDown = function(event) {
if(event.keyCode == 79 && !event.shiftKey) {
var entries = document.evaluate('//div[@id="entries"]//div[@class="entry-container"] | //div[@id="entries"]//div[@class="collapsed"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for(var i = 0, m = MAX_WINDOW_OPEN; i < entries.snapshotLength && m > 0; i++) {
var entry = entries.snapshotItem(i);
var stars = document.evaluate('.//div[contains(@class, "item-star-active")]', entry, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if(stars.snapshotLength > 0) {
var star = stars.snapshotItem(0);
var links = document.evaluate('.//h2[@class="entry-title"]/a | .//div[@class="entry-main"]/a', entry, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if(links.snapshotLength > 0) {
var link = links.snapshotItem(0);
var win = window.open(link.href);
if(win && !win.closed) {
m--;
var event = document.createEvent('MouseEvents');
event.initEvent('click', true, true);
star.dispatchEvent(event);
}
}
}
}
}
}
document.addEventListener('keydown', onKeyDown, false);
})();
(追記@2008-09-14)
ポップアップブロック等でウィンドウが開かなかった場合にスターを解除しないようにしました。
ポイント
- Google Reader 側の HTML が変更される可能性があるので、メンテしやすくしておく。今回は全て XPath を使用。
- document.evaluate の第 2 引数に document 以外のノードを指定した場合は、// を使うとルートノードから走査されることに注意。第 2 引数は単純に初期位置の指定です。ずっとそのノード以下だけが検索されると思ってました。
参考リンク
- Comments: 0
- Trackbacks: 0
iPhone 向けのタスク管理アプリを作ってみる
iPhone を買って約 1 ヶ月が立ちました。
AppStore には毎日のように新しいアプリが登場していて、うずうずしてきたのでアプリを作り始めました。
とはいってもネイティブアプリではなく、Safari 上で動く Web アプリです。
今回は iPhone 用の Safari にも組み込まれている SQLite を JavaScript から利用できる SQL API を使って、タスク管理(ToDo 管理とも呼びますね)アプリを作ってみようと思います。
せっかく iPhone 向けのアプリなので、インタフェースはやっぱりこだわりたいところ。
その iPhone 向けインタフェースのテンプレートが提供されているので、今回はそれを使いました。
iphone-universal - Google Code
まだ作成途中ですが、下記のリンクから試すことができます。Safari でアクセスしてください。
注:データベースを削除したい時は、
・通常の Safari の場合:「環境設定」→「セキュリティ」→「データベースを表示」→データベースを選択して「取り除く」
・iPhone 版 Safari の場合:「設定」→「Safari」→「Databases」→編集ボタン→削除
でできます。
今までできたところまで、ホーム画面はこんな感じです。

テンプレートのおかげで、あまり工数をかけずに iPhone 向けインタフェースができました。
そして SQLite を操作する JavaScript ソースが以下。
こちらのサイトを参考にしました。
- JavaScript++かも日記: 【iPhone】iPhone用 JavaScriptデータベースプログラミング入門 (目次)
- Safari 3.1 に実装された「Client-side database storage (SQL API)」とは何か? - IT戦記
// DB オブジェクト
var db;
// DB 初期化(テーブルが無ければ作成する)
function init() {
if(window.openDatabase) {
db = openDatabase('test_db', '1.0', 'Tasks');
db.transaction(
function(tx) {
tx.executeSql('SELECT COUNT(*) FROM tasks', [],
function(tx, rs) {},
function(tx, error) {
tx.executeSql('CREATE TABLE tasks (id INTEGER PRIMARY KEY, body TEXT, cmp_f BOOLEAN, priority INTEGER)', [],
function() {},
function(error) {
alert('Database does not created. : ' + error.message);
}
);
}
);
}
);
} else {
alert('Sorry, this browser does not supported.');
}
}
// タスク一覧を表示する
function show() {
var incmp = document.getElementById('incomplete_list');
var cmp = document.getElementById('completed_list');
if(!(incmp && cmp)) return;
// 現在表示しているタスクをクリアする
while(incmp.hasChildNodes()) {
incmp.removeChild(incmp.firstChild);
}
while(cmp.hasChildNodes()) {
cmp.removeChild(cmp.firstChild);
}
var ul = document.createElement('ul');
incmp.appendChild(ul);
var ul = document.createElement('ul');
cmp.appendChild(ul);
// タスク一覧を取得して表示する
db.transaction(
function(tx) {
tx.executeSql('SELECT * FROM tasks ORDER BY priority', [], function(tx, rs) {
for(var i = 0; i < rs.rows.length; i++) {
var row = rs.rows.item(i);
var list = (row.cmp_f == 't') ? cmp : incmp;
appendItem(list.firstChild, 'edit.html?id=' + row.id, 'arrow', row.body, row.priority);
}
// タスク件数が 0 件の場合
if(incmp.firstChild.childNodes.length == 0) {
appendItem(uncmp.firstChild, '#', null, '(No Item)', null);
}
if(cmp.firstChild.childNodes.length == 0) {
appendItem(cmp.firstChild, '#', null, '(No Item)', null);
}
});
},
function(error) {
alert('Task data does not get. : ' + error.message);
},
function() {}
);
}
// リストを追加する
function appendItem(prt, hrf, cl, val, pri) {
if(!prt) return;
var li = document.createElement('li');
li.className = 'pri' + pri;
prt.appendChild(li);
var a = document.createElement('a');
a.href = hrf;
if(cl) a.className = cl;
li.appendChild(a);
var t = document.createTextNode(val);
a.appendChild(t);
}
// タスクを新規作成する
function add() {
var b = document.getElementById('body');
if(!b) return;
var body = b.value;
var p = document.getElementById('priority');
if(!p) return;
var idx = p.selectedIndex;
var priority = p.options[idx].value;
db.transaction(
function(tx) {
tx.executeSql('INSERT INTO tasks VALUES(NULL, ?, ?, ?)', [body, 'f', priority]);
},
function(error) {
alert('Task does not create. : ' + error.message);
},
function() {
location.href = 'index.html';
}
);
}
// タスクを削除する
function del() {
var id = getIdValue();
if(!id) return;
if(window.confirm('Delete this task ?')) {
db.transaction(
function(tx) {
tx.executeSql('DELETE FROM tasks WHERE id = ?', [id]);
},
function(error) {
alert(error.message);
},
function() {
location.href = 'index.html';
}
);
}
}
// タスクを完了/未完了にする
function cmp(f) {
var id = getIdValue();
if(!id) return;
db.transaction(
function(tx) {
tx.executeSql('UPDATE tasks SET cmp_f = ? where id = ?', [(f) ? 't' : 'f', id]);
},
function(error) {
alert(error.message);
},
function() {
location.href = 'index.html';
}
);
}
// 1 つのタスクを表示する
function showOne() {
var id = getIdValue();
if(!id) return;
db.transaction(
function(tx) {
tx.executeSql('SELECT * FROM tasks WHERE id = ?', [id], function(tx, rs) {
if(rs.rows.length > 0) {
var row = rs.rows.item(0);
var body = document.getElementById('body');
if(!body) return;
body.value = row.body;
var p = document.getElementById('priority');
if(!p) return;
p.value = row.priority;
if(row.cmp_f == 't') {
var elm = document.getElementById('cmp');
} else {
var elm = document.getElementById('uncmp');
}
elm.style.display = 'none';
} else {
alert('Task does not exist.');
}
});
},
function(error) {
alert(error.message);
},
function() {}
);
}
// タスクを更新する
function update() {
var b = document.getElementById('body');
if(!b) return;
var body = b.value;
if(body.length > 0) {
var id = getIdValue();
if(!id) return;
var p = document.getElementById('priority');
if(!p) return;
var priority = p.value;
db.transaction(
function(tx) {
tx.executeSql('UPDATE tasks SET body = ?, priority = ? WHERE id = ?', [body, priority, id]);
},
function(error) {
alert('Task update failed. : ' + error.message);
},
function() {
location.href = 'index.html';
}
);
} else {
alert('Please input body.');
}
}
// QueryString から ID 値を取得する
function getIdValue() {
if(location.search.length > 0) {
var arr = location.search.substr(1).split('&');
for(idx in arr) {
var k = arr[idx].split('=');
if(k[0] == 'id') return k[1];
}
} else {
return null;
}
}
- Comments: 0
- Trackbacks: 2
- Search
- Feeds
- Meta