Archived entries for javascript

[js] Ajax通信がF5で更新されない場合

fortuneteller画像やスクリプトなどの外部ファイル取り込みを高速化するために、キャッシュ制御は不可欠です。
しかし、設定をうっかりすると(あるいは、しないと)、キャッシュが強すぎて全くデータが更新されないような場合があります。
今回のキーワードは、「IE」と「F5キー」、そして「XMLHttpRequest」。
ハイパフォーマンスWebサイト」の著者であるStevesSuders氏のblogで紹介された「F5 and XHR deep dive」を検証してみます。
Continue reading…

[js] 外部ファイルロードを便利、高速に

tricky2週間ほど前に入手したSteve Sounders氏の新刊「Even Faster Web Sites」ですが、ようやく本格的に読み始めました。
前の「ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール」は発刊前にネット上で読んでいたのでスルーしてしまいましたが、今回はちゃんと購入。前のものが基本をしっかりと抑えた王道的内容だったのに比べて、比較的トリッキーなテクニックが増えているように思います。

今回は本書の5章から「へー」と思った、外部スクリプトを他のファイルのロードを妨げることなく取得し、なおかつそのファイルのロードが終わった際に後続のスクリプトが実行されるための方法(複雑)を確認してみます。
Continue reading…

[js] 演算子+と-の速度差と最速ループ

math先週はGoogle Developer Day 2009に行ってきまして、非常に有意義なセッションもあれば、それなりのものもありましたが。

今回は個人的に最も良かったパメラさんのGoogle Maps高速化セッションから、大量マーカーの効果的なプロット方法…は、また今度時間がある時にして、その際に彼女がポロっと漏らした「+=は-=に比べて遅いし」を軽く検証してみました。(FOXでアメリカン・アイドルを観ながら)

検証は、ループカウンタをアップしていく/ダウンしていく方法で比較しています。

※2009.09.27
検証プログラムの問題を指摘いただき、末尾に追加してあります。

Continue reading…

[jQuery] スピンボタンで数値入力補助

jQuery Spin自作のjQueryプラグインを追加しました。
最近むしろあまり見なくなった(?)スピンボタンインターフェースをWebフォーム上に簡単に実装するためのプラグインです。

実はこちらのプラグインは新作ではなく、1年以上前からjQuery本家公式リポジトリGoogle Codeで公開しています。
意外なことに地味に好評で(特に海外で)、ダウンロード数も確認できるだけで累計で2,000を超えていました。バグ報告や機能追加要望も幾つかもらっていたのですが、多忙を言い訳にひたすら放置してしまっていた可哀想な子です。
今回、利用している方からメールをいただいて急にやる気が出て、ついでにgithubにプロジェクトを作ったりしながら大幅にバージョンアップして、日本語のページも用意した次第です。
今まで不便をかけていた方には、本当に申し訳ありませんでした。

jQuery Spin

概要

jQuery Spinは、jQueryのプラグインとして動作します。
入力フォームで数値を扱うことがありますが、その際の入力補助用のインターフェースです。

動作

以下のフィールドに、数値を入力します。右側の上下のスピンボタンを使うと便利です。

マウスを押したままにすると、連続して値が変化します。

使い方

まずjQuery本体が必要になります。
jQueryそのものの導入については、別途ドキュメントなどを参照してください。

jQuery Spinは、Google Codeから入手してください。

まず最初にスクリプトの配置と共に、スピンボタンの表面画像を配置しなければなりません。
画像は「押されていない状態」「上が押された状態」「下が押された状態」の3枚が必要です。
サンプルとして、ダウンロードファイルにも画像が入っているので、参考にしながら独自の見た目を作ってください。

3枚の画像は、同じディレクトリに置かなければいけません。ここでは仮に、”/images/spin/”に配置したとします。

スピンボタンの設定は、spinメソッドを呼ぶだけで簡単に行うことが出来ます。
オプションには様々なものがありますが、画像の場所指定だけはきちんと行わないと、全く動作しなくなってしまいます。

$('input').spin({imageBasePath: '/images/spin/'});

画像の場所を示すimageBasePathオプションの初期値は”/img/spin/”です。この場所に置いた場合のみ、指定は省略できます。

しかし、ページに複数のスピンボタンを設置する場合など、毎回同じオプションを指定するのも馬鹿馬鹿しい場合があります。
そんな時は、$.spinオブジェクトに値を設定することで、すべての呼び出しの初期値を変えることができます。

$.spin.imageBasePath = '/images/spin/';
$('#sample1').spin();
$('#sample2').spin();
$('#sample3').spin();

この例では、3つのspinの呼び出し全てに”/images/spin/”が適用されます。

オプション

jQuery Spinは、多くのオプションで動作を指定することができます。
オプションは多くのプラグイン同様に、メソッドの引数としてオブジェクトを渡してやることで指定できます。
指定可能なオプションは、次の通りです。

imageBasePath
スピンボタンの表面画像の配置場所を示します。初期値は”/img/spin/”ですが、ここに運良く置けるのでない限り、必須指定項目lとなるでしょう。
spinBtnImage/spinUpImage/spinDownImage
順に、「通常時」「上を押した時」「下を押した時」の画像ファイル名です。通常は変える必要は無いはずです。
interval
値の増減幅です。例えばここに”3″と指定すれば、上下ボタンで3ずつ値が変化します。小数値を設定することも可能です。
初期値は1です。
max/min
入力可能な値の最大/最小値です。但し、直接入力の値を制限したりするものではないので、バリデーションには注意してください。値を設定しない場合、制限無しを意味します。
timeInterval
スピンボタンをマウスで押しっぱなしの状態にした際に、値の変化していく時間を決めます。小さな値を設定するほど、短い間隔で値が変化します。
初期値は500(ミリ秒)です。
timeBlink
見栄えとしての上が押された/下が押された状態の画像を表示する時間です。
初期値は200(ミリ秒)です。
btnClass
ボタン画像にあてられるクラス名です。
btnCss
ボタン画像にあてられるスタイルです。指定はCSSオブジェクトの形です。
txtCss
テキストエリアにあてられるスタイルです。
lock
テキストエリアへの直接入力を禁止したい場合にtrueにします。完璧に直接入力を防げるわけではなく、過信しすぎないよう注意してください。
decimal
小数点を”.”ではなくしたい場合に指定します。例えば”,”を指定すれば、”1.8″は”1,8″になります。
beforeChange
値がスピンボタンによって変更される前に呼ばれるコールバック関数です。
第一引数にこれから変更されようとしている新しい値、第二引数には現時点の値が渡されます。戻り値にfalseを返した場合、その変更はキャンセルされます。
changed
値が変更された後に呼び出されるコールバック関数です。
buttonUp/buttonDown
上下のスピンボタンが押された際に呼び出されるコールバック関数です。値が上限を超えているなどの理由で変更されない場合にも呼び出されます。

$.spinオブジェクトの値を変えることで、オプションの初期値を変えてしまうことも可能です。

ここでは、幾つかのオプションを組み合わせた例を見てみましょう。

$('#sample1').spin({
  imageBasePath: 'http://dev.screw-axis.com/jquery-spin/demo/img/spin2/',
  interval: 10,
  max: 300,
  min: 0,
  timeInterval: 250
});

[実行結果]

プロジェクトサイト
ライセンス

コードにも記載していますが、MITとGPLのデュアルライセンスとします。
全く自由に使っていただいて構いませんが、どこかで利用したり紹介していただいた際は、ご一報いただけると喜ぶと思います。

[Web] Google Page Speedでサイトを高速化(2)

Serve前回のブラウザキャッシュの最適化に引き続き、今回は外部ファイルの取り込み時間の圧縮をやってみましょう。

最近立ち上げたサイトはこの辺の対応もしっかりしているのですが、ちょっと昔に作った管理サイトを見てみると、上位に要対応とされたのが実はこの2つ。

CSSやJsなど、ページがリッチになっていくにつれて取り込む外部ファイルも増えていきます。これらを小さくまとめて転送量を減らす工夫をすることは、ちょうどバイキングで何度も取りに行くよりも、一度に山盛りに盛ってきた方が効率が良いようなものです。
(そもそも、量を減らすことも考えなければいけませんが)
Continue reading…

[Jetpack] Screw!ボタンをつけてみる

先週、とりあえず開発環境を整えました。早速…でもないですが、何か作ってみましょう。

最初の一歩なので、カンタンなものから。
チュートリアルAPIリファレンスを見ながら、以前用意した画像がスクリューするボタンを付けてみます。

とりあえず、ボタンを表示

まずはアドレスバーに about:jetpack と入力して”I am Jetpack.”のページを表示します。
ここの”Develop”タブで開発するのが、手っ取り早い。
ページ中ほどの黒い矩形をクリックすると、Bespinのように編集可能な状態になります。
ここに、次のようなコードを入れてみましょう。

jetpack.statusBar.append({
  html: 'Screw!',
  width: 50
});

そして”try out this code”をクリック(以下、実行時には常にこの手順)
ステータスバーに”Screw!”と表示されたかと。
Continue reading…

Jetpack APIリファレンス

« Jetpack

グローバル名前空間

Jetpack Featureのグローバル名前空間には、殆どの機能が含まれています。この名前空間は、ちょうどWebページのグローバル名前空間のように見えるように作られています。

XMLHttpRequest()

XMLHttpRequestは、URLベースでデータを取得する簡単な方法を提供します。詳細についてはリファレンスを参照してください。
WebでAjax通信などで使われる同名のXMLHttpRequestと異なり、このオブジェクトは異なったドメインへのアクセスも可能です。
Jetpackが標準で搭載しているjQueryを用いることで、更に非常にシンプルにXMLHttpRequestの機能をAPIとして使うことができます。これについてはjQueryのAjaxに関するドキュメント(本家[英語])を参照してください。

clearInterval

この関数は、通常のJavascriptにおけるwindow.clearIntervalと同様に動作します。

clearTimeout

この関数は、通常のJavascriptにおけるwindow.clearTimeoutと同様に動作します。

console

このオブジェクトは、デバッグのためにFirebugコンソールにメッセージを出力する目的で使われます。log, info, warn, errorといったメソッドを、メッセージの重要度の違いによって使い分けてください。これらの関数は全て、引数を幾つでも受け取り、全ての引数はログ出力されます。

次の例は、コンソールにログを出力させます。

console.log('Hello from the Jetpack feature', this);
console.info('情報');
console.warn('警告');
console.error('エラー');
jQuery

jQueryは軽量なJavascriptライブラリです。jQueryオブジェクトは簡単に $ 関数としても使うことができます。
全てのAjaxリクエストは、jQueryによって提供されているクロスサイトで利用可能なXMLHttpRequestオブジェクトで行われています。
より詳細な情報は、jQuery本家(英語)もしくは、非公式ですがjQuery日本語リファレンスなどを参照してください。

jetpack

名前空間 “jetpack” は全てのJetpack Featureで利用可能な、Firefoxの機能にアクセスする主要なポイントになるものです。このAPIは、Mozillaプラットフォームへの後方互換の軽量な受付口として設計されています。これは、Jetpackライブラリを用いてFeatureを書けば、Firefoxがバージョンアップしてもコードを書き換える必要が無いことを意味します。

jetpack.notifications

最終的に、このオブジェクトはユーザへ簡単に通知を送る手段の全てになるでしょう。通知バー、透過メッセージ、Growls、ドアノブメッセージなどがここに集約されていきます。現在のところは、単純な通知機能だけです。

jetpack.notifications.show(options)

[オプション]

title String
通知タイトル。
icon URL
通知アイコンのURL。
body String
通知内容。

この関数はシンプルな通知メッセージを表示します。WindowsとLinuxではトースター通知で、MacのOS XであればGrowlメッセージ(インストールされていれば)になります。引数は1つで、通知文字列か、title, icon, bodyなどのプロパティを持つオブジェクトを受け取ります。iconを設定する場合、そのURLを渡す必要があります。

以下の例は、オブジェクト指定の場合です。

jetpack.notifications.show({
         title: 'hai2u',
         body: 'o hai.',
         icon: 'http://www.mozilla.org/favicon.ico'
});
jetpack.slideBar

このオブジェクトは、ブラウザ上のタブ左側にあるアイコンへマウスを近づけることで自動的に開閉する、Jetpackによって追加されたスライドバーに関するものです。Featureはアイコンを追加したり、追加コンテンツを表示するためにスライドバーを開いたり、ページに戻るためにスライドして閉じたりすることが出来ます。

このスライドバー機能は、現時点では実験的なものです。以下のコードでロードされます。

jetpack.future.import("slideBar");
jetpack.slideBar.append(options)

[オプション]

icon String
スライドバーが開いた際に表示される最初のアイコン。
html String
新しいスライドバーの最初のHTML。プレーンテキストもしくはE4X形式で記述。
url URL
スライドバーにロードするHTMLのURL。前述のhtmlが設定されていた場合、そちらが優先されます。
width Number
htmlやurlで指定したページのレンダリングされるサイズをピクセル単位で指定。
onSelect Function
アイコンをクリックして選択された際に呼び出されるコールバック関数。既にFeatureが選択状態にある場合は、重ねてonSelectが呼び出されることはありません。関数の引数については下記を参照。
onReady Function
スライドバーにコンテンツがロードされた際に呼び出されるコールバック関数。関数の引数については下記参照。

この機能はスライドバーにアイコンを追加します。スライドバーは、スライドバーアイコンにマウスが近づくと表示されます。ユーザがFeature毎のアイコンをクリックすると、そのFeatureは「選択状態」になり、例えば更に広いエリアにスライドバーを開き、Feature用のコンテンツを表示するなどの追加アクションを実行することが出来ます。

全てのコールバック関数は唯一の引数として、スライドバーの開閉に使われるslide()を受け取ることができます。slide()はslideBar.append関数のように、オプションオブジェクトを1つ受け取ります。このオプションはsizeとpersistという2種類のプロパティがあります。sizeはスライドバーが開くピクセル数です。persistはbool値で、trueの場合はユーザがマウスカーソルをスライドバーの外に出しても、自動的に閉じずに待機します。

slide()はプロパティオブジェクトで、2つの追加プロパティを持ちます。iconはスライドバー中のアイコンを指し、docはFeature用のドキュメントを指します。これらはリスナーを追加したり、動的にアイコンやドキュメントを変更する際に便利です。

スライドバーを閉じるには、引数を渡さずに単にslide()を呼ぶだけです。

次の例は、アイコンをクリックして選択すると一時的にスライドバーを広げ、広げられたコンテンツ部分をクリックするとスライドバーを開いたままにさせる機能をスライドバーに追加します。(閉じるには、スライドバーアイコンをクリックします) 更に、コンテンツがクリックされた際にFeatureのアイコンも変更します。

jetpack.future.import("slideBar");
jetpack.slideBar.append({
  onSelect: function(slide) slide({ size: 100 }),
  onReady: function(slide) $(slide.doc).click(function() {
    slide({ size: 200, persist: true });
    slide.icon.src = "chrome://branding/content/icon48.png";
  })
});

コールバック関数の引数で渡されたslideにpersistが指定されない場合、スライドバーは実際にはブラウザの右端の位置をウィンドウの外にシフトさせていることに注意してください。about:jetpackの例で見れば、リファレンスページはウィンドウの中心に位置しています。それが、FFアイコンをクリックした状態ではコンテンツ部分の右に寄る(中心に来ない)と思います。これは、この時点ではスライドバーのコンテンツは一時的なものであるからです。persitがtrueに設定された場合は、それによって圧迫されたコンテンツ部分が再描画され、この時点での右端を縁とします。

jetpack.statusBar

このオブジェクトは、ブラウザ下部にあるステータスバー関連の関数を包括しています。このステータスバーは、Firefoxの[表示]メニューにあるオプションでユーザが非表示にしている場合もあることを覚えておいてください。

jetpack.statusBar.append(options)

[オプション]

html String
新たなステータスバーパネルのHTML。
url URL
ステータスバーパネルにロードされるHTMLのURL。
width Number
htmlやurlで指定されたコンテンツが描画されるサイズをピクセル単位で指定。
onReady Function
ステータスバー上に新しいパネルが作られた際に呼び出されるコールバック関数。

この関数は、開いている全てのウインドウ上のステータスバーに新たなパネルを追加します。新たなブラウザを開けば、自動的hにそこにもパネルが追加されます。

技術的に言うと、ステータスバーパネルはifrmae要素です。これはリソースを大量に消費しますが、Webが備えている全てのジェネレート機能を有します。将来的にはこの関数に、よりシンプルでリソース消費の少ない、静的ラベルや画像を表示するようなオプションが追加されるかもしれません。

以下のサンプルではステータスバーにアイコンを追加します。そしてそのアイコンをクリックすると、通知メッセージが表示されます。

jetpack.statusBar.append({
  html: '',
  width: 16,
  onReady: function(doc) {
    $(doc).find("img").click(function() {
      jetpack.notifications.show("hai2u");
      });
  }});
jetpack.storage

このオブジェクトは、恒久的な或いは一時的な全てのストレージを含むものです。

jetpack.storage.live

jetpack.storage.lliveに、どんなオブジェクトでも結びつけることが出来、Firefoxが再起動されるまでいつでも利用することができます。

jetpack.storage.live.myData = {hello: "world"};
console.log( jetpack.storage.live.myData );
jetpack.storage.simple

Simple Persistent Storage JEPを参照してください。
シンプル・ストレージは各Jetpack Feature毎に区切られているので、他の開発者が書いたコードと衝突することを恐れる必要がなくなります。
以下に、シンプル・ストレージAPIの使い方を簡単に例示します。

jetpack.future.import("storage.simple");
jetpack.storage.simple.set( "4ever", {hello:"world"} );
jetpack.storage.simple.get( "4ever", function(data, value){
  console.log( data, value );
});
jetpack.tabs

jetpack.tabsはタブ関連のプロパティを備えた、動的な配列です。

jetpack.tabs.focused

現在フォーカスされアクティブになっているタブオブジェクトです。

以下のサンプルでは、現在フォーカスを得ているタブのURLを通知します。

jetpack.notifications.show(jetpack.tabs.focused.url);
jetpack.tabs.onFocus(callback)

タブオブジェクトが選択状態になった際に常に呼ばれるliveイベントをバインドします。
このバインダー関数はタブオブジェクトもしくはjetpack.tabs配列上で利用できます。
登録されたイベントハンドラは、現時点では引数を何も取りません。関数が呼び出された際、thisで引き金となったタブオブジェクトを参照できます。
次のサンプルはjetpack.tabs.onFocusハンドラを使い、タブを切り替えた際には常に通知メッセージを表示するようにしています。

jetpack.tabs.onFocus(function() {
  jetpack.notifications.show("You selected " + this.url);
  });
jetpack.tabs.onReady(callback)

“live event binder”は、タブオブジェクトのHTML文書もしくは、それが含むサブドキュメント(例えばiframeのような)のひとつのロードが終わった際に、このイベントを実行します。純粋に技術的な見地で言えば、このイベントはターゲットとなるドキュメントの DOMContentLoaded イベントにより実行されます。

このバインド用メソッドは、タブオブジェクトとjetpack.tabs配列で利用可能です。

次のサンプルコードはjetpack.tabs.onReadyハンドラを用いて、ユーザがページへ再訪した際に通知メッセージを表示できるようにしています。

jetpack.tabs.onReady(function onNextPage(doc) {
  if (!doc.defaultView.frameElement) {
    jetpack.notifications.show("Loaded " + doc.location.href);
    jetpack.tabs.onReady.unbind(onNextPage);
  }});
location

この文字列は、機能のコードを示すURLになります。

以下の例は、現在のロケーションをコンソールに表示させます。

console.log(location);
setInterval

この関数は、window.setIntervalと同様に動作します。

setTimeout

この関数は、window.setTimeoutと同様に動作します。

Tabオブジェクト

Tabは、ブラウザのタブに関する機能を提供します。

close()

タブを閉じます。既にタブが閉じられている場合は、何もしません。

contentDocument

タブが現在表示しているHTMLドキュメント。タブが閉じられている場合、値はnullになります。

contentWindow

現在タブが表示しているWindow。(タブ内のWebページにとっては、これがウインドウとして認識されています) タブが閉じている場合、値はnullになります。

favicon

タブが表示しているfaviconのURL文字列。タブがfaviconを持っていない場合や閉じられている場合、値はnullになります。

focus()

タブを選択状態にします。

isClosed

タブが閉じられているかどうかを示すbool値。これは例えば、タブオブジェクトを変数に入れて保持しておき、後でその値を利用する際に既に閉じられていないかを確認するような場合に使えます。

onFocus(callback)

Tabオブジェクトが選択状態になった際に、常に呼び出されるライブイベントをバインドします。
このバインダー関数は、Tabオブジェクトやjetpack.tabs配列上で利用できます。
ここでバインドされた関数は、現時点では引数を何も取りません。呼び出された際は、this変数で引き金になったTabオブジェクトにアクセスできます。
次のサンプルはjetpack.tabs.onFocusハンドラを使い、タブを切り替えた際には常に通知メッセージを表示するようにしています。

jetpack.tabs.onFocus(function() {
  jetpack.notifications.show("You selected " + this.url);
  });
onReady(callback)

“live event binder”は、タブオブジェクトのHTML文書もしくは、それが含むサブドキュメント(例えばiframeのような)のひとつのロードが終わった際に、このイベントを実行します。純粋に技術的な見地で言えば、このイベントはターゲットとなるドキュメントの DOMContentLoaded イベントにより実行されます。

このバインド用メソッドは、タブオブジェクトとjetpack.tabs配列で利用可能です。

次のサンプルコードはjetpack.tabs.onReadyハンドラを用いて、ユーザがページへ再訪した際に通知メッセージを表示できるようにしています。

jetpack.tabs.onReady(function onNextPage(doc) {
  if (!doc.defaultView.frameElement) {
    jetpack.notifications.show("Loaded " + doc.location.href);
    jetpack.tabs.onReady.unbind(onNextPage);
  }});
raw

XULのTabオブジェクトに直接アクセスします。このオブジェクトはMozillaプラットフォームでの変更を受けやすいので、アクセスは最終手段として極力使わないようにしてください。
タブが閉じている場合、値はnullになります。

url

タブが現在表示しているURL文字列。タブが閉じている場合、値はnullになります。

« Jetpack

[Javascript] nullとundefinedとfalseと0と空文字と

大抵の、特に変数の型宣言を行わないタイプの言語では、型の異なる値の条件式は悩みの種です。
Javascriptもご他聞に洩れずというか、undefinedとnullが異なる分だけ更にややこしくなっているようです。
暗黙の型変換で痛い目にあわないよう、ちょっと実験してまとめてみます。
実験にはとりあえず、手っ取り早いので Jash を使用。
一緒に試してみるならば、こちらのBookmarkletをクリックしてコンソールに入力しながら読むとわかりやすいかもしれません。

nullとundefined

nullとundefined。たまに「同じもの?」と聞かれることもあるので、とりあえず確かめて見ます。

>> null==undefined
true

あれ、同じでしょうか?
Continue reading…

jQuery 自作プラグイン3 “Type-Writing Hint”

続けて3本目。jQuery Type-Writing Hintです。

jQuery Type-Writing Hint

こちらも、作者の方で紹介ページなど作る前にskuare.net様でご紹介いただいており、大変ありがたいのですが。

「ちょっとうざい」

ええ、自覚しておりますとも。
ちょっと新しいかなと思って作ってみたのですが、正直言って、スパム広告の一部みたいに見えたりします。
おかげさまでGoogleで「jQuery ちょっとうざい」と検索すれば一番に出てくるようになりました。
ま、それも味かなと思って、とりあえず並べておきます。

それなりに工夫している点もありまして、最たるものは、普通にJavascriptを操作しても入力ヒントが文字列とみなされないこと。
何も考えずにこのテのものを作ると、例えば

alert(text.value);

のように書いても、実際はユーザは何も入力していないのにヒント文字列が表示されてしまったりすることがあります。
# WordPressの管理画面にある「新規タグの追加」なんかもそうですね。黙って「追加」を押すと、「新規タグの追加」というタグが出来ます。
それがコイツは、ちゃんとヒント文は空文字として、手で入力した文字はそれとして、認識されます。
このプラグインを見たカナダの会社から仕事のオファーをいただいたり、なかなか頑張ってくれた子です。



Copyright © 2004–2009. All rights reserved.

RSS Feed. This blog is proudly powered by Wordpress.