2009年9月27日日曜日

Firebug で JavaScript の関数の実行時間を計測する

1. console.time() で関数の実行時間を測る

Firebug で、JavaScript の関数の実行時間を知りたい。

例えば、HTML の pre 要素内で JavaScript ファイルを読み込むとする。

index.html

<html>
    <head></head>
    <body>
        <pre><script src="test.js"></script></pre>
    </body>
</html>

JavaScript のファイルである test.js の中で、console.time(), console.timeEnd() 関数を使うと、関数が実行される時間を測ることができる。

Firebug and Logging によると、

The low-fi approach is to call console.time("timing foo") before the code you want to measure, and then console.timeEnd("timing foo") afterwards.

test.js において、hoge 関数の実行時間を知りたい場合、次のように記述する。

var hoge = function(){
	for (var i = 0; i < 100; i++) {
		document.writeln("hoge");
	}
}

console.time("hoge");
hoge();
console.timeEnd("hoge");

Firebug のコンソールを開き、index.html にアクセスすると、hoge の実行時間が表示される。

090927-006.png

 

2. console.profile() で関数の実行結果を詳しく得る

console.profile() 関数を使うと、console.time() よりも情報を得られる。

The high-fi approach is to use the JavaScript profiler. Just call console.profile() before the code you want to measure, and then console.profileEnd() afterwards

(同上より)

例えば、test.js に piyo 関数を追加し、hoge 関数と piyo 関数実行時間を測る。

var piyo = function(){
	var _piyo = function(){
		for (var i = 0; i < 100; i++) {
			document.writeln("piyo");
		}
	}();
}

console.profile("test");
hoge();
piyo();
console.profileEnd();

index.html を開いて、先ほどと同じくコンソールを見ると、console.time() よりも多くの情報が表示される。

090927-008.png

 

参考

Flickr へのアップロードは Firefox Universal Uploader で

1. jUploadr はアップロードした後の通知が鬱陶しい

ブログを書くとき、写真の置き場に Flickr を使っている。

アップロードするためのツールは jUploadr を利用。jUploadr でも純正のツールと同じように、アップロードが完了すると通知のダイアログが表示される。通知に対応しなければならいので面倒だった。 (+_+)

 

2. Firefox Universal Uploader は通知してこない

これに対して、Firefox Universal Uploader (fireuploader) は、アップロードが終ってもダイアログで通知してこない。 ^^ これに乗り換えよ~。

行頭のタブを空白(スペース)に変換 - サクラエディタ, Notepad++, Eclipse, Emacs での使い方

1. ソースコードのインデントには タブ or 空白 ?

ソースコードにはタブよりも、空白を使う方が適している。

ただし、インデントはタブかホワイトスペースか? という議論がある。

[ThinkIT] 第5回:フォーマットに関するコーディング規約 (3/4) によると、

インデントにタブを使っていると、エディタの設定によって見た目が異なり、可読性が落ちる場合がありますので、タブのかわりに空白文字を使うとよいでしょう。この場合の空白文字の個数ですが、4文字にすると見やすくなります。

 

a. タブのほうが適切だという意見

これに対して、mieki256's diary - Rubyコーディング規約 には、空白よりもタブ派という意見が 2 つ引用されている。

_ インデント - ただのにっき (2003-02-13) :

はっきりいって、空白を使った固定インデントにはどうしても馴染めないのだよ。インデント幅なんて、見る人がいちばん気持ちがいい値に合わせられた方がいいに決まってるじゃないか。

_最速インターフェース研究会 :: タブとスペースと萌ディタの話

タブの幅を自分好みにしたいっていうと解決策は色々あるんだろうけど、一番手っ取り早いのはタブを使うことなんじゃないの?タブを使ってインデントしてればエディタの設定だけでファイルの内容に手を加えずに見た目だけ変えられるから楽。

コメント: もうやらなくていい昔のコーディングテクニックあれこれ – スラッシュドット・ジャパン には、

ソースコードにおけるインデントとは、プログラムの文書構造を視覚的に表現するための手段です。視覚的に表現できれば何でも良いのでタブでも空白4 文字でも8文字でも本来であれば問題ありません。しかしながら多くの場合、繰り返し流用や保守作業を続けていくと、空白で表現されたインデントは崩れやすく、コードブロックの判別が難しくなる傾向があります。6文字や7文字といった切りの悪い数の空白のインデントが散在し始めると、どこまでを一つのブロックと判断してよいのか分からなくなり、可読性を大きく損ないます。

タブの場合は、一文字でインデント一つを表現できるので保守性が向上します。また、タブが一文字削除されるとインデント一つ分大きく変動するので異常を即座に見つけやすいという利点もあります。

 

b. タブが問題となるのはパッチ

タブの問題点について言及している。

皆さんの多くがタブを使いがちなのは知っていますが、 実際問題、分散開発環境においては、cvs コミットメッセージがメーリングリストに送られるとき、 タブを使った場合、ほとんど読めないという事があるのです。

http://www.ingrid.org/jajakarta/cactus/xdoc/coding_conventions.xml  より)

404 Blog Not Found:タブのスペース化はタブ幅よりも重要である

君たちは、patchのことをきれいさぱーり忘れている。

人のコードを直したり、人にコードを直してもらったりしなくてもいいというのであれば、君たちのいい分ももっともだ。しかし、人とコードをやりとりする時にpatchをやりとりする場合、tabは頭が痛い以外の何者でもない。

 

2. サクラエディでタブを空白に変換

ブログにソースコードを貼るとき、タブを空白に変換する必要がある。

サクラエディタでは、

  • メニューより「変換 > TAB→空白

を選択する。

 

3. Notepad++ でタブを空白に変換。デフォルトでタブを空白に。

a. 既存のタブを空白へ変換する

Notepad++ で、既に作成してある文書内のタブを空白に変換したい場合は、変換したい部分を選択した後、

  • メニューより、TextFX > TextFX Edit > Leading space to tabs or to spaces

を選択する。

090927-002.png

 

b. 新規に作成する文書のための環境設定

新たに文章を作成したときに、タブを入力したら、空白を入力して欲しい場合、

  • メニューより、設定 > 環境設定 > エディット画面 > Tab Setting

Replace by space にチェックを付ける。

090927-001.png

追記 (2010.2.26) : 上記の「エディット画面」に Tab Setting がない場合、

  • 言語メニュー」のタブ設定

の「スペース置換」にチェックを入れる。

img07-02-2010[1]

 

4. Eclipse, Aptana でタブを空白に設定

Eclipse, Aptana の場合、

  1. メニューより Window > Preferences...
  2. Aptana > Editors > General > Tab Insertion

において、Use spaces を選択する。

091005-001

 

5. Emacs, Meadow, xyzzy でタブを空白に変換

  1. 変換したい範囲を選択する。
    • 変換したい範囲の先頭 で Ctrl + Space
    • 変換したい範囲の最後までカーソルを移動する
  2. M-x untabify

逆に空白をタブにしたい場合は、範囲を選択しておいて M-x tabify 。

 

参考

タスク切り替えユーティリティ「窓替え」を見やすい設定に

B0028AEE6QPC の画面が小さいので仮想デスクトップを使っていたけれど、最近全然使っていない。そうすると必然的に見える範囲でウィンドウを切り替えるか、タスクバー、もしくは、Alt + Tab で切り替える羽目に。しかし、たくさんアプリを起動しているので結構大変。 (+_+) あぁ~、でかいモニタ欲しい。。

それにしても、標準のタスク切り替えの Alt + Tab は使いにくい。直前に使っていたものに切り替えるのには都合がいいけれど。bb4win_mod を使っていたときに利用していた 窓替え をまた使うことにしよう。

 

表示を大きく

デフォルトの設定ままでは字が小さくて視認性が良くないので設定を変更。

タスクトレイにある「窓替え」を右クリック > 「オプション」 を選択。

設定画面の「表示 > リスト」 のフォントを メイリオ してサイズを 10pt に変更。

090927-003.png

 

これだと Alt + Q で表示させる窓替えの横幅広すぎるので、「表示> ウィンドウ > ウィンドウスタイル」の横幅を 500 ピクセルに設定。

090927-004.png

 

関連記事

JavaScript でマウススクロールしたときのイベント処理

1. マウススクロールに応じたイベント処理

JavaScript で生成した DOM Element を、マウススクロールに合わせて移動させたい。

位置を固定する

要素を固定するには、CSS の position 属性を absolute にする。これにより、イベント処理をしなければ、マウススクロールしても固定した位置に留まる。

スクロール量を知る

JavaScript で、スクロール量を知るには、window オブジェクトの scrollY プロパティを利用する。scrollY は、

文書が垂直スクロールされているピクセル数を返します。

イベントの設定

エレメントにイベントを設定するには、

を使う。このメソッドの使い方は、以下を参照。

マウスホイールの動きに対応するには、 Gecko-Specific DOM Events – MDC の  DOMMouseScroll を使う。

The DOMMouseScroll event is sent when the mouse wheel is moved. The target of this event is the element that was under the mouse pointer when the mouse wheel was scrolled, similar to the click event.

これにより、マウスホイールをスクロールさせたときに、直下にある要素にイベントが伝わる。

イベントの要素への伝わり方は、以下を参照。

イベントハンドラからW3C DOMイベントモデルへ

まずドキュメントツリーの上から下に向けてイベントが伝搬します。これをキャプチャー・フェーズと呼びます。

次に目的の要素にイベントが伝搬しますが,これをターゲット・フェーズと呼びます。ちなみに,この目的の要素のことを,ターゲットノードと呼びます。

しかし,ここで終わりではなく,さらに今度はターゲットノードからドキュメントツリーの上に向けてイベントが伝搬します。この段階をバブリング・フェーズと呼びます。

このように,W3C DOMイベントモデルでは,ドキュメントツリーの上からイベント発生源まで伝搬し,そして,今度は逆の方向に伝搬するという概念を持っています。イベントは,そのイベントが発生した部分だけでしか認識されないわけではない点に注意してください。

 

2. 例

HTML の div 要素を作成し、マウススクロールに合わせて移動させる。

var newElem = document.createElement("div");
var p = document.body.firstChild;
newElem.innerHTML = "挿入";
p.parentNode.insertBefore(newElem, p);

// 初期の位置
var x = 30, y = 30;
with(newElem.style){
    // 大きさ
    width = "100px";
    height = "100px";
    // 位置
    position = "absolute";
    top = y.toString() + "px";
    left = x.toString() + "px";
    // 背景の色
    backgroundColor = "red";
    // 透過度
    opacity = "0.7";
}

// マウススクロールに対するイベント処理
addEventListener("DOMMouseScroll", function(e){
    with(newElem.style){
        top = (y + scrollY).toString() + "px";
        left = (x + scrollY).toString() + "px";
    }
}, false);

 

数値を文字列に変換

数値を文字列に変換するメソッドは toString

全てのオブジェクトは toString メソッドを持ち、オブジェクトが文字列値として表されるべきときや、文字列が期待される構文で参照されたときに自動的に呼び出されます。

toString - Number オブジェクトのメソッド によると、

指定された Number オブジェクトを表す 文字列を返します。

JavaScript で XML を読み込む

DOMParser で XML を DOM ツリーに変換する

Firefox で XMLを解析し、DOM ツリーを生成するには、DOMParser を使う。

Parsing and serializing XML – MDC によると、

Mozilla は現時点では W3C の Document Object Model Load and Save に対応していない ( bug 155749) ので、DOM ツリーをシリアライズおよびデシリアライズするには次の Mozilla 専用のインターフェイスを使うのが最も簡単です。…

  • DOMParser - XML を文字列から DOM ツリーにパースする

例えば、「名前」と「年齢」を含む XML から、名前のみを抽出する。

var theString = '<persons>' +
	'<person><name>太郎</name><age>20</age></person>' +
	'<person><name>次郎</name><age>25</age></person>' +
	'<person><name>花子</name><age>30</age></person>' +
	'</persons>';
var parser = new DOMParser();
var dom = parser.parseFromString(theString, "text/xml");
var persons = dom.getElementsByTagName("person");
for (var i=0; i<persons.length; i++){
	console.log(persons[i].getElementsByTagName("name")[0].textContent);
}

Firebug のコンソールで実行した結果は、

太郎
次郎
花子

XML に対して、HTML で要素を取得するときに使う getElementsByTagName メソッドを利用している。これは、getElementsByTagName メソッドが定義されている Document インターフェイスは、HTML と XML を表現したものであるため。

2009年9月26日土曜日

JavaScript で半透明な固定した領域を生成する

1. CSS で要素を固定し、半透明にする

JavaScript で半透明な固定した領域を生成したい。

要素の位置を固定するには、HTML において、CSS の position プロパティを fixed にする。

絶対的な位置に固定配置する によると、

「position:fixed」と距離を指定するプロパティは、指定された要素を絶対的に移動させて配置しますが、その要素はウィンドウ上のその位置に固定されて、スクロールしても位置が変わらなくなります

要素を半透明にするには、CSS で filter プロパティを設定する。

IE・Firefox・Opera・Netscape・Safariで表示可能な半透明CSS/Opacityテクニック - WEBデザイン BLOG によると、

以下のコードでIE・Firefox・Opera・Netscape・Safariで同等表示がえられます。

  filter: alpha(opacity=25);
  -moz-opacity:0.25;
  opacity:0.25;

 

2. JavaScript で要素を生成し、CSS のプロパティを設定する

JavaScript で DOM Element を生成し、CSS を設定する。

DOM Element を生成する方法は、以下を参照。

CSS を設定するには、element.style を利用する。

var newElem = document.createElement("div");
var p = document.body.firstChild;    // この要素の前に newElem を挿入 
newElem.innerHTML = "挿入";
p.parentNode.insertBefore(newElem, p);

with(newElem.style){
    // 大きさ
    width = "100px";
    height = "100px";
    // 位置
    position = "fixed";
    top = "30px";
    left = "30px";
    // 背景の色
    backgroundColor = "red";
    // 透過度
    opacity = "0.7";
}

 

関連記事

Google ブックマークを XML で取得

Google Bookmarks API Guide によると、

Google is a leader in the publication of its services through public interfaces such as the ones for Search, Google Maps, …. However, they have not yet published an API for Google Boomarks.

うーん、何で API が公開されていないのだろう。 (?_?) 不思議。。

上記に続いて、以下のようにリバースエンジニアリングした結果が書かれている。特定の基準で検索したい場合、以下のような URL にアクセス。

Lookup one record given a certain criteria

http://www.google.com/bookmarks/lookup?q=label:label2&output=xml

(同上より)

output=xml と付けると XML で返してくれるようだ。

試しに Google ブックマークで `hoge’ と検索したと想定して、以下の URL でアクセス。

http://www.google.com/bookmarks/lookup?q=hoge&output=xml

しかし、どうも結果が違う。 (@_@;)

 

普通に Google ブックマークで検索すると、上記 URL 中にある lookup ではなく find なので、

http://www.google.com/bookmarks/find?output=xml&q=hoge

に変更したらちゃんと表示された。

 

取得数

取得できるデータ数に関するパラメータについても説明があった。

XML Data Access

Parameters:

num=a large number (if parameter is ommited, only 25 bookmarks are returned)

(同上より)

先ほど表示できた URL の末尾に &num=100 と付けてアクセスしてみた。

http://www.google.com/bookmarks/find?output=xml&q=hoge&num=100

普通に検索したとき `hoge’ の検索が 25 件以上ある場合、100 件を上限に表示してくれるようだ。ただし、 num=3 のように小さい値にしても変化はなかった。

 

JavaScript でアクセス

上記を元に JavaScript でアクセスする。ただし、日本語で検索するときは URL エンコードするのを忘れずに。

var url = "http://www.google.com/bookmarks/find?output=xml&q=";
var q = "ほげ";
location.href = url + encodeURIComponent(q);

JavaScript で CSS の float 属性を設定する

1. DOM Element を右に寄せたい

DOM Element を生成し、右に寄せたい。

そのために、element.style.float を設定したが、要素を右に寄せることができなかった。 (+_+)

var newElem = document.createElement("div");
var p = document.body.firstChild;    // この要素の前に newElem を挿入 
newElem.innerHTML = "挿入";
p.parentNode.insertBefore(newElem, p);

newElem.style.float = "right";

 

2. float ではなく cssFloat 属性を設定する

右寄せをするには、element.sytle.cssFloat 属性を利用する。

UchのX40記: [JavaScript]DOM Elementのstyle属性のfloat (via floatが動かない - くれすの開発日記〔JavaScript編〕 - g:javascript) によると、

IEやと

(DOM Element).style.styleFloat = "left";

Firefoxやと
(DOM Element).style.cssFloat = "left";


OperaやとどっちでもOK。

先ほどの右寄せを設定しているコードを、以下のように変更。

newElem.style.cssFloat = "right";

なぜ Float の前に css と接頭辞があるのだろう?

 

3. DOM の仕様

DOM の仕様を確認してみる。

Document Object Model – Wikipedia によると、

  • Document Object Model (DOM) Level 2 Style Specification
  • Document Object Model Style SheetsIndex で `float’ と検索したら、確かに cssFloat となっていた。

    cssFloat of type DOMString
    See the float property definition in CSS2.

    JavaScript で要素をタグ名により取得し、テキストの内容を表示する

    1. 要素をタグ名で取得

    JavaScript で要素をタグ名で取得するには、

    getElementsByTagName メソッド

    を用いる。

    例えば、HTML の div 要素を取得するには、

    document.getElementsByTagname("div");

    ちなみに、getElementsByTagName メソッドの Elements の `s’ をよく忘れ、エラーになることがある。 (+_+)

    このメソッドは、Document インターフェイスで定義されている。

    Interface Document

    The Document interface represents the entire HTML or XML document. …

    getElementsByTagName

    Returns a NodeList of all the Elements with a given tag name in the order in which they are encountered in a preorder traversal of the Document tree.

    Parameters

    tagname of type DOMString
    The name of the tag to match on. The special value "*" matches all tags.

    Return Value

    NodeList

    A new NodeList object containing all the matched Elements.

     

    インデックスで要素にアクセスする

    getElementsByTagName によって返されるオブジェクトは NodeList 。

    Document Object Model Core

    getElementsByTagName

    Returns a NodeList of all the Elements with a given tag name in the order in which they are encountered in a preorder traversal of the Document tree.

    NodeList は、配列のようにインデックスで要素にアクセスできる。

    Interface NodeList

    The NodeList interface provides the abstraction of an ordered collection of nodes, …

    The items in the NodeList are accessible via an integral index, starting from 0.

    div 要素の 0 番目の要素を取得するには、

    document.getElementsByTagname("div")[0];

     

    2. テキストの内容を表示

    要素を取得したら、その内容を表示したい。そのためには、Node オブジェクトに定義されている textContent 属性を取得する。

    textContetDocument Object Model CoreInterface Node に定義されている。

    textContent of type DOMString, introduced in DOM Level 3
    This attribute returns the text content of this node and its descendants.

    div 要素の 0 番目の要素のテキストを取得するには、

    document.getElementsByTagname("div")[0].textContent;

    JavaScript で正規表現

    JavaScript で正規表現を使いたい。

    JavaScript: The Good Parts (p75) によると、

    4873113911JavaScript において正規表現が利用できるメソッドは、regexp.exec, regexp.test, string.match, string.replace, string.search, string.split である。

    RegExp, string ごとにメソッドを整理。

    RegExp

    string

  • exec
  • test
  • match
  • replace
  • search
  • split
  •  

    String.match

    String オブジェクトの match メソッドを試す。

    "abcdef123".match(/(b.).*(\d{3})/)

    結果は、

    ["bcdef123", "bc", "123"]

    match – MDC によると、

    正規表現が g フラグを含んでいない場合、regexp.exec(string) と同じ結果を返します。

    exec メソッドは、

    特定の文字列でのマッチのための検索を実行します。結果の配列、あるいは、null が返ります。

    結果として返される配列の中身は、

    [1], ...[n]
    括弧で囲まれた部分文字列のマッチ。括弧で囲まれた部分文字列の数に制限はありません。

    (同上より)

     

    例えば、

    Google の検索において、検索した文字列を取得したい。

    Google で検索した後のURL を見ると、クエリ文字列のパラメータ q の値が検索文字列のようなので、

    decodeURIComponent(location.search.match(/q=(.*?)&/)[1]);

     

    location.search と decodeURIComponent

    上記 location.search は「JavaScript で URL からフラグメント以外を取得」を参照。

    decodeURIComponent メソッドは、

    エンコードされた URI の要素内のエスケープシーケンスをそれぞれが表す文字に置き換えます。

     

    最左最短一致

    正規表現における

    .*?

    はの意味は、

    量指定子の後ろに?を付けると、最短でマッチさせます。この最左最短一致を「なまけもの(non-greedy)マッチ」とも言います

    (量と位置を指定する via Yahoo! Pipes で、RSS を出力してないサイトをRSS化する より)

    2009年9月22日火曜日

    Google Chrome で pbtweet – User Script を使って

    1. 会話のコンテキストを表示してくれる pbtweet

    Twitter のメリットが今一良くわからない。

    たまにつぶやいてみるけれど、何のためにつぶやいているのかわからなくなる。 ^^; 「つぶやくこと」が目的ではなく、情報収集のためのツールとなっているかな。

     

    Seesmic で検索を保存して、意外な出会い

    しかし、Seesmic を使うまでは全く Twitter の意義を見出せなかった。

    Seemic では、興味のある単語をいくつか検索し保存しておく。保存した検索から、思わぬ発見に出会えることがある。

    例えば、自分の住んでいる地域で検索しておくと、ローカルな話題がリアルタイムに近い状態で見れておもしろい。

    しかし、問題はつぶやいた人に興味を持ち、「他にどんなことをつぶやいているのだろうか?」とTwitter のページを見ても読みにくいこと。個々のつぶやきを読んでも意味不明で、どういうコンテキストで誰と何の会話をしているのかわからない。 (+_+)

     

    コンテキストを表示してくれる pbtweet

    これを解消してくれたのが pbtweet

    会話のコンテキストを表示してくれる。チャットを読んでいるように感じる。

    見しらぬ人の Twitter を見ても読みやすいし、インライン表示された部分は会話がされている。重要な情報が得らやすい。会話から人のつながりを辿って行くのもおもしろい。

    追記(2009.11.21) : 現在、PBTweet+ を使うようになった。(ページがハングル文字だったので、Google 翻訳 を利用) 「Userscript + Chrome」と書かれた箇所からインストール。 これ以降の設定は必要ない。

     

    2. Google Chrome は Safari の仲間だから pbtweet を利用できる

    しかし、残念なことに Firefox では動作しなかった。

    pbtweet - twitter拡張スクリプト - によると、

    インターフェイスにはいくつかのアニメーション効果が追加されますが、これらはWebKitのCSS 3先行実装を用いています。

    WebKit とは 、 WebKit – Wikipedia によると、

    Mac OS X v10.3以降に搭載されているMac OS X標準のWebブラウザSafariの基礎を成している。…
    Googleは、Google Chromeや携帯電話プラットフォームAndroidで採用している

    なるほど、Chrome は Safari の仲間だったのか。(@_@) そこで、Twitter は Google Chrome で見ることにした。

    ただし、pbtweet をブックマークレットで使う場合、別の人の twitter に飛ぶとブックマークレットの効果がなくなってしまう。 (+_+) この際、ブックマークレットを使わないですむように、Chrome で userscript が動作するようにした。

    追記 (2010.3.18) : 現在は PBTweet+ を Google Chrome, Firefox の双方で使うことができる。

     

    3. Google Chrome を Dev channel へ

    Chrome では安定版、ベータ版、開発版のことをチャンネルという言葉で表現している。

    Early Access Release Channels によると、

    Google Chrome releases updates to different release channels. Subscribing to the Beta or Dev channel means you'll get more frequent (but less stable) updates and you'll get to try new features first.

    Subscribing to a channel で `Dev channel’ に切り替える。 Dev channel をクリックしてインストール。

    http://dev.chromium.org/getting-involved/dev-channel#TOC-Windows

    追記 (2009.11.10) : Google Chrome のバージョンが 4.0.237.0 にアップデートされたら、下記の「UserScript の利用」の設定が必要なくなった。pbtweet - twitter拡張スクリプト - の userscript の pbtweet.user.js をクリックすると、

    Extensions and themes can harm your computer. Are you sure you want to contine ?

    と尋ねられるので、「続行」 ボタンを押してインストール。これだけで済む。

     

    4. User Script の利用

    User Scripts を参考に。

    • Install a recent trunk build of Chromium, or switch to the dev channel.
    • Launch chrome.exe with the --enable-user-scripts flag.
    • Create a directory called User Scripts in your user data directory.
    • Copy *.user.js files to the script directory.
    • Script edits are picked up automatically; just refresh the page to see the changes.

    既に dev channel に切り替えたので、起動時のオプションを付けるところから。

    • スタートメニュー > すべてのプログラム > Google Chrome

    の中の Google Chrome を右クリック > プロパティを表示。

    090921-002.png 

    ショートカットのリンク先に --enable-user-scripts  を追加。

    090921-003.png

    スクリプトを保存するための User Scripts フォルダは、User Data Directory によると、

    Google Chrome: C:\Documents and Settings\<username>\Local Settings\Application Data\Google\Chrome\User Data\Default

    の中に作成する。この場所を間違えないように注意。

    最初、動かなくておかしいなぁと思ったら、User Data の中に間違えて作っていた。もう一つ下の Default フォルダの中に作ること。

     

    5. pbtweet の userscript

    pbtweet - twitter拡張スクリプト – の userscript を先ほど作成した User Scripts フォルダへ保存。

    これで快適な Twitter ライフが送れそうだ。 ^^

     

    参考

    2009年9月20日日曜日

    JavaScript で外部サイトのフィードを取得 - Google AJAX Feed API を利用

    0. 目次

    1. 公式 HP と、外部ブログを組み合わせる事例が多い
    2. ユーザが HP を更新したいなら、CMS を利用するのがいい
    3. 外部ブログのフィードを取得する方法
    4. Google AJAX API
    5. Google AJAX Feed API
    6. フィードを取得するためのソースコード

     

    1. 公式 HP と、外部ブログを組み合わせる事例が多い

    見かけよりも、サイトの内容が大事

    090918-006企業サイトを見ていると、公式 HP とは別に、ブログは外部サービスを利用している例を見かける。

    「金かけてるのに、自社の紹介とブログが別って、何で?」

    CMS を使って、一体感のあるデザインにした方がいいと思うけれど、別々の例をいくつか見ていたら、次第に慣れてきた。

    「それでも、まぁいいかぁ~」

    という気になる。

    Flash を中心に構築しているサイトであれば、ブログを組み込むのは手間がかかるだろう。

    Twitter の興隆っぷりを見ていると、発信する媒体の統一性など、受信してくれる価値に比べたら微々たるもの。情報が文脈から切り離され、情報としてのみ価値を有し、デザインは二の次というのは潔い。RSS フィードを受信することが習慣化するにつれ、ますますそういう意識に陥る。見かけよりも中身が大事。

     

    されど見かけも重要

    しかし、デザインに全体的な統一感があると、サイトをはじめて見る人にしてみれば、内容の理解がしやすい。まとまって見える分記憶に残りやすい。

    「ちゃんとしたところだな」

    という感じを演出できる。

    以前、それほど PC に詳しくない人から、

    「ブログはホームページではないですよね?」

    と言われたことがある。最初、その意味がわからなかった。できあいのシステムを利用したブログと、所謂 HP 作成用のソフトで作ったものとは、別のものだと認識しているようだ。感覚として、そこに境界を感じるらしい。

    そういう認識を持つ人にとって、ブログでサイトを作って

    「これホームページにしておきませんか?」

    というのは通じない。体面が大事な企業の HP が、Blogger で何のカスタマイズもされていなかったら、

    「ここ大丈夫か?」

    と思ってしまう感覚は理解できる。人は、見かけで判断することもあると。

    追記 (2010.5.3) : ダダ漏れ東京女子流 のインタビューが配信されているのを見た。そのグループのサイトを見たら、一目で色々なサービスを利用していることがわかるデザインだった。公式サイトは看板で、個別の内容は各々のサービスを参照という形が、最近益々不自然でない印象を受ける。

     

    2. ユーザが HP を更新したいなら、CMS を利用するのがいい

    年間少しのお金を出せば、ドメインとサーバスペースを取得できる。できあいのブログが嫌なら、CMS をインストールすれば、快適な環境が得らえる。

    しかし、既にプロバイダーと契約していると、容量が少ないながら無料でホームページ用のスペースを持っていることが多い。既にその場に HP を作っている場合、

    「アドレスを変えたくないし、無料のスペースがあるのでこれ以上はお金をかけたくない。」

    と考える人がいる。そういう心情も理解できなくはない。しかし、加えて

    「でも、ブログのように自分で HP の内容を更新したい。」

    となると、ちょっと悩んでしまう。 (+_+) 

    サーバの仕様によっては CGI が使えるので、CMS で置き換えることもできる。しかし、無料の場合、制約が多くて無理なことも多い。もし、Perl が使えるなら、シンプルで軽そうな blosxom は良さげ。これでも処理が重たく感じられるようなサーバなら、別の手を考えるしかない。

     

    3. 外部ブログのフィードを取得する方法

    HP にとって、アドレスは昔ほど意味を持たなくなっている。単語を検索して、辿りつくのが普通。

    であるなら、既存の HP は潰して、別の URL へリダイレクトさせるだけの役割を持たせればいい。しかし、今あるものは、それはそれで活用したい場合、どうしよう?

    苦肉の策として、日々更新したい内容は、外部のブログで更新。そのフィードを、スクレイピングして既存のホームページに表示する。

    しかし、制約があって、サーバに RSS を取得するライブラリをインストールして利用する方法がわからなかったら、どうしよう?

    JavaScript: 外部RSS読み込み by “Google Ajax Feeds API” | t.p.fields - web+tech info  によると、

    とあるお仕事でJavaScriptを用いて外部RSSを読み込む作業をすることになった。…

    JavaScriptでのクロスドメイン処理は難しいので、”Google Ajax Feeds API“を使わせてもらうことにした。

    “Google Ajax Feeds API”は、かの有名なGoogleが提供してくれる、RSS/Atomなどの各種フィードを取得するためのJavaScript API。

    なるほど、これを使って外部ブログのフィードを読み込み HP に表示すればいい訳か。

    そこで、以下の図のような構成を想定。

    1. HP には、トップページに日々更新した内容を表示。
    2. レイアウトは 2段組で、左側にはブログのタイトルの一覧を表示し、右側にはその内容を配置。
    3. ブログの内容は、外部ブログからまるごと取得して表示。
    4. 内容の右下の「前の投稿」のリンクは、トップページに表示した記事よりも前の投稿へのリンク。このリンクにより外部ブログへ飛ぶ。

    090918-005

    これで、既存の HP はそのままで、ブログを使ってユーザが更新できる。ブラウザの JavaScript が有効であれば、見かけそのままで、HP のアドレスを変更する必要もない。かなり強引な方法だけれど。。 ^^;

     

    4. Google AJAX API

    Home Page - Google AJAX API によると、

    Google AJAX API では、リッチでダイナミックなウェブサイトを JavaScript と HTML だけで実装できます。JavaScript コードを数行追加するだけで、自分のサイトに地図動的な検索ボックスを追加したり、フィードをダウンロードできます。

    この中に Google AJAX Feed API がある。

    デベロッパー ガイド - Google AJAX API もチェック。共通の枠組みについて説明がされている。

     

    5. Google AJAX Feed API

    Google AJAX Feed API によると、

    AJAX Feed API を使用すると、JavaScript だけを使用して、公開されている Atom フィードや RSS フィードをダウンロードできるので、自分のコンテンツや Google Maps API などの他の API に、フィードを簡単にマッシュアップできます。

    早速利用方法から見ていく。

    AJAX API キーの使用 によると、

    この API を使用するためにキーは必要ありません。アプリケーションやサイトでキーを使用するかどうかは、完全に任意です

    今回は AJAX API キーは利用しない。

    この API が扱いやすそうなのは、JSON 形式と XML 形式の結果 によると、

    AJAX Feed API の JSON 形式は、オリジナルのフィードを簡素化し、標準化したものです。これにより Atom および RSS の titledescriptionsummary などの属性が共通の JSON プロパティにマッピングされるので、Atom フィードにも RSS フィードも統一的に利用できます。

    必要な情報は JSON 形式の結果 を見ればよい。

    予め承知しておくことは、

    AJAX Feed API は Feedfetcher を使用しているため、API から提供されるフィードのデータが最新ではない場合もあります。Google のフィード クローラ (Feedfetcher) がフィードを取得する頻度は、ほとんどのサイトでは 1 時間に 1 回を超えることはありません。一部の頻繁にアップデートされるサイトに対しては、更新の頻度が高くなります。

    (フィードのクロール頻度 より)

    外部ブログの投稿がリアルタイムに HP の方に更新されることはない。pubsubhubbub でリアルタイムになるといいのだけれどなぁ。

     

    6. フィードを取得するためのソースコード

    表示

    index.html

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     <head>
      <link rel="stylesheet" type="text/css" href ="gajax.css"></link>
      <script type="text/javascript" src="blog.js"></script>
      <script type="text/javascript" src="http://www.google.com/jsapi"></script>
      <script type="text/javascript" src="gajax.js"></script>
     </head>
     <body>
      <!-- フィードのタイトル一覧 -->
      <div id="feedTitle"></div>
      
      <div id="main">
       <!-- フィードの内容 -->
       <div id="feed"></div>
       <!--前の投稿へのリンク -->
       <div id="nextLink"></div>
      </div>
     </body>
    </html>

     

    gajax.css

    基礎編1 フロートを使ってみる を参考に CSS で段組。

    #feedTitle { 
     font-size: small;
     float:left;
     padding: 10px;
     width: 30%;
    }
    #main {
     float:left;
     width: 67%;
    }
    #nextLink {
     text-align: right;
    }
    .title { font-size: x-large; }
    .content { padding: 20px; }

     

    Google AJAX Feed API の利用

    gajax.js

    はじめての Google AJAX Feed API を元に作成。先ほどのデベロッパー ガイド - Google AJAX API も参考に。

    以下のコードは、冒頭の blog オブジェクトで、対象の外部ブログのフィード URL と、1 ページに表示する投稿数、外部ブログの URL を指定。

    その他以下を参照。

    ブログのエントリーの公開日時の扱いは、Date オブジェクトを生成してから使うことに気をつける。

    publishedDate

    エントリが公開された日付の、「13 Apr 2007 12:40:07 -0700」という形式の文字列。new Date(entry.date) を使って日付を解析することができます。

    (JSON 形式の結果 より)

    var blog = { 
     feedurl: "http://jutememo.blogspot.com/feeds/posts/default",
     numOfPost: 7, // 1 ページに表示する投稿数
     url: "http://jutememo.blogspot.com/"
    }
    
    // エントリーのタイトルをリンク付きにして div 要素に入れて返す。
    function createTitleWithLink(entry, idx){
     var div = document.createElement("div");
     var anchor = document.createElement("a");
     anchor.href = entry.link;
     anchor.setAttribute("name", idx);
     anchor.appendChild(document.createTextNode(entry.title));
     div.className = "title";
     div.appendChild(anchor);
     return div;
    }
    // エントリーの内容を div 要素に入れて返す。
    function createContent(entry){
     var div = document.createElement("div");
     div.innerHTML = entry.content;
     div.className = "content";
     return div;
    }
    // エントリーのタイトルへのアンカーを作成し、div 要素に入れて返す。
    function createFeedTitle(entry, idx){
     var anchor = document.createElement("a");
     var div = document.createElement("div");
     anchor.setAttribute("href", 
      location.protocol + "//" + location.hostname + location.pathname + "#" + idx);
     anchor.appendChild(document.createTextNode(entry.title));
     div.appendChild(anchor);
     return div;
    }
    // 「前の投稿」を生成
    // createURL 関数は blog.js で定義。
    function createNextLink(entry){
     var anchor = document.createElement("a");
     anchor.href = createURL(blog.url, blog.numOfPost, new Date(entry.publishedDate));
     anchor.appendChild(document.createTextNode("前の投稿"));
     return anchor;
    }
    google.load("feeds", "1");
    function initialize() {
     var feed = new google.feeds.Feed(blog.feedurl);
     feed.setNumEntries(blog.numOfPost)
     feed.load(function(result) {
      if (!result.error) {
       var divFeedTitle = document.getElementById("feedTitle");
       var divFeed = document.getElementById("feed");
       var divNextLink = document.getElementById("nextLink");
       for (var i = 0; i < result.feed.entries.length; i++) {
        var entry = result.feed.entries[i];
        // フィードのタイトル一覧を生成
        divFeedTitle.appendChild(createFeedTitle(entry, i));
        // フィードのタイトルを生成
        divFeed.appendChild(createTitleWithLink(entry, i));
        // フィードの内容を生成
        divFeed.appendChild(createContent(entry));
       }
       // 前の投稿へのリンクを生成
       divNextLink.appendChild(createNextLink(result.feed.entries[blog.numOfPost-1]));
      }
      });
    }
    google.setOnLoadCallback(initialize);

     

    Blogger における「前の投稿」へのリンク

    blog.js

    JavaScript で Blogger の「前の投稿」へのリンクを生成 を参照。

    // Blogger の場合
    
    // num が一桁の数字のとき先頭に 0 を加えて二桁にする
    function padzero(num){
     return ("" + num).length == 1 ? "0" + num : num;
    }
    function format(date){
     return date.getFullYear() + "-" + 
      padzero(date.getMonth()+1) + "-" + 
      padzero(date.getDate()) +
      encodeURIComponent("T" + padzero(date.getHours()) + ":" + 
       date.getMinutes() + ":" + 
       padzero(date.getSeconds()) + "+") +
      "09:00";
    }
    function createURL(url, numOfPost, date){
     return url + "search?updated-max=" + format(date) + "&max-results=" + numOfPost;
    }

    JavaScript で URL からフラグメント以外を取得

    1. URL の # 以降の文字列

    ウェブページで、特定の場所にアンカーを指定するには、要素の属性に id または name を指定する。これにより、特定の場所へ # を使いリンクを貼ることができる。

    この # 以降の文字列は、フラグメント識別子と言う。

    フラグメント識別子とは - はてなキーワード によると、

    id属性やa要素のname属性で指定するアレ」の正式名称。

    例えば、http://ja.wikipedia.org/wiki/Javascript#.E6.AD.B4.E5.8F.B2 からフラグメントを取得するには、

    location.hash

    逆に、フラグメント以外を取得するには、

    location.protocol + "//" + location.hostname + location.pathname

     

    2. クエリ文字列

    クエリ文字列とは、URL に含まれる `?’ 以降の文字列のこと。

    「クエリー文字列」とは:ITpro によると、

    URLの「?」以降に格納する文字列。Webアプリケーションでは,クエリー文字列をよく利用する。例えば,クエリー文字列にユーザー識別子を格納してセッションを維持したり,データベースを検索するための文字列を指定する。

    例えば、Google 検索をした後に、

    location.search

    を実行すると、クエリ文字列を取得できる。それにしても、何でプロパティ名が search なんだろう?

    location.search では ? を含めた文字列が返される。? を取り除きたい場合は、

    location.search.substring(1)

    2009年9月19日土曜日

    コカコーラゼロより、ペプシネックス方が美味しい理由

    1. コーラと言えばコカ・コーラ

    今年はコーラをがぶ飲みしている。カロリーのことを考え、カロリーゼロの方を購入。

    「コーラ」と言えば、ペプシよりもコカ・コーラを連想する。

    「コーラ」と言えば?8割が「コカ・コーラ」 ~「ペプシ」派の6割は「味」と「カロリー」に“こだわり” | rTYPE アイシェアオンラインリサーチサービス 市場調査公開 によると、

    「『コーラ』と言えば、コカ・コーラ、ペプシコーラどちらか」を聞いたところ、全体の80.2%が「コカ・コーラ」と回答。

    昔、ペプシコーラを飲んだとき、まずかった。そのため、コカコーラを箱買いした。

     

    2. ペプシコーラがうまい!

    先日、たまたまペプシコーラが激安だったので購入した。飲んでみたら普通に飲めた。 (@_@)

    ペプシコーラを飲んだ後、コカコーラを飲んだら、どこか物足りなく感じた。。 (@_@;) あれ?

    PEPSI NEX 急成長の理由|∞最前線 通信 によると、

    なぜ、PEPSI NEX は 美味しいのでしょうか?

    私は、ペットボトルの裏側の成分を

    じっくり見てみました

    レモンキラキラが入ってたのですね!

    パワーアップしてペプシコーラに近づいた「ペプシネックス」 – GIGAZINE には、

    飲んだところ、パワーアップを実感させる味になっていた。まず、以前のネックスはちょっとぼやけた感じの味だったのに対して、今度のは酸味というか、深みが増えた。ゼロカロリーは変わっていないのに、味はネックスよりもペプシに寄ったという印象がある。これはパワーアップ成功ですね。

    なるほど、随分以前からこういう味になってたのか。 ^^

    JavaScript で a 要素を生成し、name 属性を設定するときは DOCTYPE 宣言と setAttribute メソッドを使用する

    1. IE8 で a 要素の name 属性が生成されない

    JavaScript で、HTML の「ページの特定の場所を示すアンカー要素」を生成した。

    結果を Firefox で表示すると、アンカー要素が正常に生成された。しかし、Internet Explorer 8 では想定していた属性名が生成されなかった。

    このとき、特定の場所を示すために a 要素の

    • name 属性

    を利用していた。

    例えば、次のように JavaScript で a 要素を生成し、name 属性を設定した後、HTML の要素として挿入する。

    <html>
    	<head></head>
    	<body>
    	</body>
    	<script type="text/javascript">
    	var anchor = document.createElement('a');
    	anchor.name = "hoge";
    	anchor.appendChild(document.createTextNode('hoge'));
    	document.body.appendChild(anchor);
    	</script>
    </html>

    Firefox において、Firebug で上記のHTML を確認すると、

    <a name="hoge">hoge</a>

    IE8 の DebugBar で確認すると

    <a submitName="hoge">

    name 属性ではなく、 submitName 属性になっている。これにより、アンカーが機能しない。

     

    2. a 要素で name 属性を使うことは問題ない

    name 属性を使うことは、問題があるのだろうか?

    文書の特定の場所へのリンク」 によると、

    リンク先には、文書中の特定の段落など具体的な場所(フラグメントといいます)を指定することもできます。フラグメントを示すには、対象となる要素にid属性を使って名前を付けます(古いブラウザとの互換性のためには、アンカー要素の2番目の役割であるname属性による名前付け機能を使うこともできます)

    では、なぜ name 属性が勝手に変ってしまったんだろう?

     

    3. DOM の createElement メソッドで生成したオブジェクトに対する属性の指定

    アンカー要素を生成するために、createElements メソッドを利用した。

    DOM の createElements で生成したオブジェクトは、その属性を直接設定できる。

    Document Object Model (Core) Level 1 によると、

    createElement

    Creates an element of the type specified. Note that the instance returned implements the Element interface, so attributes can be specified directly on the returned object.

    例えば、img タグに対応したオブジェクトを生成し、その src 属性を設定してみる。

    var img = document.createElement('img');
    img.src = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkfqT1erWUZHM7qxkaPs5aIS-NDQx5dDTg4_VnLNKq8AP7b0iAJei3pGnwVMtnottNtucRtfl8YLKbb9vYjIoiD09LWvZYOrrqtAUcyrIIQJIo0vqy-KMJDL70gmC4Nf80e-snbvOqdZw/s220/profile.png";
    document.body.appendChild(img);

    上記のコードは、 Firefox, IE の両方で問題なく動作する。

    先ほどの引用中に `the instance returned implements the Element interface’ とあった。よって、Interface ElementsetAttribute メソッドを使い、属性を設定することもできる。

    var img = document.createElement('img');
    img.setAttribute("src", "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkfqT1erWUZHM7qxkaPs5aIS-NDQx5dDTg4_VnLNKq8AP7b0iAJei3pGnwVMtnottNtucRtfl8YLKbb9vYjIoiD09LWvZYOrrqtAUcyrIIQJIo0vqy-KMJDL70gmC4Nf80e-snbvOqdZw/s220/profile.png");
    document.body.appendChild(img);

    setAttribute メソッドを使い、アンカー要素の  name 属性を設定してみた。

    anchor.setAttribute("name", "hoge");

    しかし、これだけでは、結果は変わらなかった。 (+_+)

     

    4. DOCTYPE スイッチで Standards モードでレタリングする

    文書の先頭で DOCTYPE を、キチンと設定しないとダメだろうか?

    IE8 では、DOCTYPE を指定しないと、互換モードでレタリングされる。

    IE8のレンダリングモードと互換表示 - page2 - builder by ZDNet Japan によると、

    レンダリングモードはIE6の時代から採用されてきたDOCTYPE宣言による指定か、IE8で採用されたMETAタグまたはHTTPレスポンスヘッダによる指定で切り替えることができる。…

    IE8ではDOCTYPE宣言によってIE8 StandardsモードとQuirksモードが切り替わる。

    問題のソースコードを IE8 で開き、DebugBar を起動。メニューの右隅を見ると `Quirks’ と表示された。

    090919-008

    DOCTYPE 宣言による「解釈モード」の切り替え によると、

    過去の慣習的な解釈を再現するモード (Quirks mode)

    仕様準拠の厳格解釈モード (Standards mode)

    では、Standards モードでは、アンカー要素を表示させることはできるだろうか?

    モードを変更するには、IE8のレンダリングモードと互換表示 - page2 - builder by ZDNet Japan によると、

    IE8 StandardsモードになるDOCTYPE宣言の記述
    • HTML4.01 Transitional/FramesetのDOCTYPE宣言でシステム識別子(DTDのURL)を記述している場合
      • (例)
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    • HTML4.01 StrictのDOCTYPE宣言を記述している場合
      • (例)
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    • XHTML1.0のDOCTYPE宣言を記述している場合
      • (例)
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    問題のコードの先頭に DOCTYPE 宣言を書き Standard モードでレタリングするようにした。

    属性を直接設定する方法でアンカー要素を生成したら、a 要素が以下のようになった。 (@_@;)

    <a propdescname="hoge">

    これに対して、属性を setAttribute メソッドを使った場合、問題なくアンカー要素が生成された。

    上記をまとめると、

    1. DOCTYPE 宣言により Standard モードでレタリングし、
    2. setAttribute メソッドを使えば良い。
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    	<head></head>
    	<body>
    	</body>
    	<script type="text/javascript">
    	var anchor = document.createElement('a');
    	anchor.setAttribute("name", "hoge");
    	anchor.appendChild(document.createTextNode('hoge'));
    	document.body.appendChild(anchor);
    	</script>
    </html>

    上記の DOCTYPE は、IE6 でも標準準拠モードになる。

    また、システム識別子がついていないだけで、動作ががらっと変ってしまう。

    「システム識別子」とは、DOCTYPE 宣言による「解釈モード」の切り替え によると、

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
       "http://www.w3.org/TR/html4/strict.dtd">

    "-//W3C//DTD HTML 4.01//EN" の部分は「 公開識別子 」と呼ばれます。…

    "http://www.w3.org/TR/html4/strict.dtd" は、この W3C HTML 4.01 の文法を定義しているモノ (DTD) のありかです。「 システム識別子 」と呼ばれます。

     

    5. クロスブラウザ対策

    ところで、Setting the “name” attribute in Internet Explorer » Semicolon には、次のように MSDN における説明が引用されている。

    I found an explanation in the MSDN DHTML reference, on the page describing the NAME Attribute.

    “The NAME attribute cannot be set at run time on elements dynamically created with the createElement method. To create an element with a name attribute, include the attribute and value when using the createElement method.”

    以下の記述により、Quirks モードとなり、 DOCTYPE を書かなくても良いようだ。

    var anchor = document.createElement("<a name='hoge'>");
    anchor.appendChild(document.createTextNode('hoge'));
    document.body.appendChild(anchor);

    しかし、残念ながら  Firefox では動かない。 (+_+)

    には、クロスブラウザ対策がされているコードが書かれている。

     

    6. jQuery で DOM エレメントを生成する

    jQuery を使うなら、DOCTYPE を宣言しなくてもちゃんと表示された。

    利用したメソッドは次の二つ。

    <html>
    	<head>
    		<script type="text/javascript" src="jquery-1.3.2.js"></script>
    		<script type="text/javascript">
    		$(document).ready(function(){
    			$("<a name='hoge'>hoge</a>").appendTo("body");
    		});
    		</script>
    	</head>
    	<body>
    	</body>
    </html>

    ただし、IE8 では、先ほどの DOCTYPE を記述したり、

    $("<a>").append("hoge").attr("name", "hoge").appendTo("body");

    または、以下のように記述すると、

    $("<a name='hoge'>").append("hoge").appendTo("body");

    正常に表示されない。Firefox では、問題ないのだけれど。

     

    7. まとめ

    • DOCTYPE 宣言して、setAttribute メソッド使う。
    • jQuery なら $ メソッドにおいて、属性と中身を含んだ HTML をごっそり引数として渡す。

    てゆうか、name 属性は使わない方がいいのかな?

    2009年9月18日金曜日

    JavaScript で Blogger の「前の投稿」へのリンクを生成

    Blogger の画面右下にある「前の投稿」へのリンクを作りたい。

     

    どうするか?

    今トップページの一番下にある記事の下にある「前の投稿」のリンクを見ると、

    http://jutememo.blogspot.com/search?updated-max=2009-09-11T08%3A40%3A00%2B09%3A00&max-results=5

    文字エンコードされているように見えるので、 decodeURIComponent – MDC を使いデコード。

    decodeURIComponent("http://jutememo.blogspot.com/search?updated-max=2009-09-11T08%3A40%3A00%2B09%3A00&max-results=5")

    結果は、

    http://jutememo.blogspot.com/search?updated-max=2009-09-11T08:40:00+09:00&max-results=5

    パラメータを見ると、

    • updated-max
    • max-results

    updated-max は指定した日付と時間よりも前の記事を指定しており、max-results は 1 ページに表示する記事の数を表わしているようだ。

     

    方法

    日付の操作は Date – MDC を参照。注意することは、

    month
    1 月を意味する 0 から 12 月を意味する 11 までの、月を表す整数値。

    「Blogger のドメイン、表示する投稿の数、年月日」を指定すると「前の投稿」のリンクを生成する createURL 関数を定義する。

    // num が一桁の数字のとき先頭に 0 を加えて二桁にする
    function padzero(num){
    	return ("" + num).length == 1 ? "0" + num : num
    }
    function format(date){
    	return date.getFullYear() + "-" + 
    		padzero(date.getMonth()+1) + "-" + 
    		padzero(date.getDate()) +
    		encodeURIComponent("T" + padzero(date.getHours()) + ":" + 
    			date.getMinutes() + ":" + 
    			padzero(date.getSeconds()) + "+") +
    		"09:00"
    }
    function createURL(url, numOfPost, year, month, date){
    	return url + "search?updated-max=" + 
    		format(new Date(year, month-1, date)) +
    		"&max-results=" + numOfPost
    }

     

    自分のブログで 2008/4/9 よりも前の投稿を 10 件表示する URL を作成するには、

    createURL("http://jutememo.blogspot.com/", 10, 2008, 4, 9);

    結果は、

    http://jutememo.blogspot.com/search?updated-max=2008-04-09T00%3A0%3A00%2B09:00&max-results=10

    2009年9月17日木曜日

    JavaScript で特定の要素の前に要素を挿入する

    1. DOM で要素を作成し、挿入する

    例えば、JavaScript を使い、body 要素の直後に div 要素を挿入したいとする。

    document – MDC のメソッドによると、

    element のメソッドには、

    これらを使って、コードを書く。

    var newElem = document.createElement("div");
    newElem.innerHTML = "挿入";
    document.body.insertBefore(newElem, document.body.firstChild);

     

    element.parentNode

    追記 (2009.9.26) : 4.7. Inserting content before an element [Dive Into Greasemonkey] では、親要素を指定するのに、element.parentNode を利用している。

    var newElem = document.createElement("div");
    var p = document.body.firstChild;   // この要素の前に挿入したい
    newElem.innerHTML = "挿入";
    p.parentNode.insertBefore(newElem, p);

     

    iframe 要素を挿入

    div 要素の代わりに iframe 要素を挿入したい場合は、

    var frame = document.createElement("iframe");
    frame.src = "https://developer.mozilla.org/en/Gecko_DOM_Reference";
    frame.width = 500;
    frame.height = 500;
    document.body.insertBefore(frame, document.body.firstChild);

    当初、document のプロパティを見て、要素の中身を書くために

    を利用すれば良いと考えた。しかし、Node.textContet には問題がある。

    IEではtextContentは使えないので、この命令を使う場合にはブラウザのタイプ判定による場合分けが必要。

    (innerTextとtextContent - javascript 覚え書き日記 - g:javascript より)

    Node.textContent の代わりに、innerHTML を利用した。

    タグの中身を取得するにはinnerHTMLを使う。

    他に整形テキストを取得するinnterTextと、タグ自身を含む文字列を取得するouterHTMLがあるが、結論から言うとこの2つはFireFoxでは利用できない。innerHTMLのみが共通仕様。他にも微妙に違いがある。

    (innerHTMLとか(IEとFireFoxの差異) - perl 覚え書き日記 - Hatena::Group::Perl より)

     

    2. jQuery で要素を生成し、挿入する

    同じことを jQuery を使って書きたい。

    要素を追加するために after(content) を利用する。

    after(content)

    各要素の後ろにコンテンツを挿入する。

    引数
    content

    String,Element,jQuery

    追加する文字列、DOM ElementおよびjQueryオブジェクト

    追加する内容は、文字列で指定する。 DOM Element でも指定できるということは、先ほどのように createElement メソッドを使って生成したものを指定できるようだ。

    $(document).ready(function(){
    	$("body").after("<div>挿入</div>");
    });

    iframe 要素を追加するには、

    $(document).ready(function(){
    	$("body").after('<iframe ' +
    		'src="https://developer.mozilla.org/en/Gecko_DOM_Reference"' +
    		'width="500" height="500" />');
    });

    2009年9月15日火曜日

    NIKEiD の myLOCKER が使えない

    追記 (2009.9.25) : やっと日本語でロッカーに保存できるようになった。 ^^


    靴は New Balance を長いこと愛用している。久しぶりに新しく購入しようと思い、Javari で試したらどうもしっくりこない。仕方がないので今回は NIKE に。サイトを見たら NIKEiD でカスタマイズしたオリジナルの靴を作れるようだ。

    デザインしたものを保存できるロッカー機能があったので、NIKEiD に登録。しかし、丁度システムのメンテナンスの時期だったのでこの機能を使えず。 パタッ(o_ _)o~†

     

    対策

    英語版ではロッカー機能が使えたので言語を変更して使う。

     

    最初に「日本語」の状態でログインしておく。(英語版ではログインできないときがあったため。)

    NIKEiD のトップページの左下の COUNTRY SELECTOR をクリック。

    090915-003.png

     

    ENGLISH > USA を選択。

    090915-004.png

     

    英語版ではデザインした後 `Save and Share’ をクリックすると、Save to myLocker が表示された。

    090915-005.png

    とりあえず、これでロッカーには保存されるようになった。

    Ubiquity が正常に動作しない

    Firefox のアドオン ubiquity を使って Gmail に Google Map を貼り付けようとしたら動作しなかった。

     

    対策

    Ctrl + Space で Ubiquity を呼出し、help コマンド。

    メニュー より 「設定」の「言語設定」の 「Parser 2 (次世代パーサ)を使用」のチェックをはずして、再起動したら動作した。

    090915-001

     

    tinyurl のコマンドも正常に動作しないと思ったら、これが原因だったのか。。 (+_+)

     

    参考

    2009年9月13日日曜日

    COOKPAD を Google で画像付きで検索 – Ready2Search で検索プラグインを作成

    1. COOKPAD のレシピを検索したい

    料理を作ろうと クックパッド でレシピを検索した。「人気順」で並び換えを行おうとしたら、「プレミアサービスへの登録」が必要だった。パタッ(o_ _)o~†

    COOKPAD を Google で検索する方法がある。

    COOKPADをGoogleで人気順に検索するFirefox検索プラグイン / ichiroc.in によると、

    でもこれってGoogleのPageRankの理論で、かなりのところまでいけるんじゃね?

    ってことで試してみたら意外といけたので、Ready2Searchを利用してFirefoxの検索プラグインにして組み込む事にした。

    COOKPAD Google検索 Firefox 検索プラグイン

     

    2. PageRank と Ready2Search

    上記の「PageRankの理論」とは、ページランク – Wikipedia によると、

    PageRankアルゴリズムの発想は、引用に基づく学術論文の評価に似ている。

    1. 学術論文の重要性を測る指標としては、被引用数がよく使われる。重要な論文はたくさんの人によって引用されるので、被引用数が多くなると考えられる。同様に、注目に値する重要なウェブページはたくさんのページからリンクされると考えられる。

    Ready2Search:日本語 は、

    Ready2SearchはInternet Explorer 7、Firefox、Googleツールバーで使える検索プラグインを作成することができます。

     

    3. 検索するときに画像を表示

    090912-005

    Google の「検索ツール」には、「画像表示」がある。これを利用して、料理の画像も表示させたい。

    試しに、「画像表示」で検索し、関連する URL のパラメータを絞り込むと、

    • tbs=img:1 が、画像の表示
    • tbo=1 が、サイドバー

    に対応しているようだ。

    先ほどの COOKPAD Google検索 Firefox 検索プラグイン を元に、

    検索ワードの後」フィールド

    に &tbo=1&tbs=img:1 を追加した。

    Ready2Search(COOKPAD)

     

    Google ツールバーの場合

    追記 (2009.10.18) : Google ツールバーを使っている場合は、上記のReady2Search(COOKPAD)を開き、Google ツールバープラグインの方をクリック。

    イントールが終わると、検索ボタン 091018-014 の一つとして表示される。

    使い方は、検索フィールドに単語を入力すると、ボタンに虫めがねのアイコンが小さく表示される 091018-013 ので、その状態でボタンを押す。アイコンが 091018-014 の状態のときは、検索フィールドに単語が入力されていても検索されないことに注意。

    2009年9月11日金曜日

    短縮 URL サービス TinyURL から bit.ly へ乗り換えた

    1. URL が長い場合、短縮 URL サービスを利用する

    Amazon にある商品の URL は長い。このような場合、URL を短かくするには、URL 短縮サービスを利用すれば良い。

    最近では bit.ly が Twitter に採用されたことで有名になった。

    URL短縮戦争:TwitterがTinyURLを捨て、bit.lyを採用によると、

    いつの間にかTwitterは標準のURL短縮サービスをTinyURLからbit.lyに置き換えたのだ。bit.lyはスタートしたばかりで、TinyURLと同様のサービスを提供する。

     

    2. 短縮 URL を作成するブックマークレット

    短縮 URL を作成するには、ブックマークレットを使うと良い。bit.ly のブックマークレットはTools にある。

    `bit.ly Sidebar’ を試したところ、リンクを作成したいページから遷移することなく URL を取得できる。ページのタイトルを含んだ URL wo作成してくれるので便利。

    追記(2014/8/12): ブックマークレット bit.ly Sidebar を HTTPS のページでも利用できるように

     

    3. アカウントを作ってリンクを保存

    bit.ly はアカウントを作成して利用すると良い。なぜなら、作成したリンクを保存してくれるため。

    bit.ly, a simple url shortener によると、

    Complete History

    Access the complete history of your bit.ly links

    ただし、作成したリンクは公開したくないので、account settings における `History Privacy’ の `Make bit.ly history public.’ のチェックははずしておいた。