メイン

「jQuery」のアーカイブ

2008年7月 5日

jQuery plugin : color-utils.js リリース

以前、JUIに参加したときに、「jQuery pluginとしてリリースします」と言ってほったらかしになっていたcolor-utils.jsをリリースしました。

jquery-color-utils - Google Code

使い方等のドキュメントは↓こちら。

Document - jquery-color-utils - Google Code

RGB(rbb(n,n.n))表記を、16進表記(#nnnnnn)に変換したり、rgbの値を与えて色を変更したり、色の平均値を出したり、背景色でHTML Elementをソートしたりできます。

まあ、普通のアプリでは、あまり使われることはなさそうですかね。

テストを先日紹介したQUnitで書いているので、興味がある方はテストのページもご覧ください。

QUnit sample

ダウンロードは↓コチラのページから。

jquery-color-utils - Google Code

2008年7月 2日

jQuery Search

Google Custom Search Engineを使って、jQueryの公式サイトと、jQueryのGoogle Groupを検索する検索エンジンを作りました。

関数や不具合報告の検索に役立つと良いな(といっても、検索先が英語なので、ちょっと敷居が高いかもしれませんが)。

jQuery Search

2008年6月15日

jQueryのテスティングフレームワークQUnit

jQueryのSubversionリポジトリにtestフォルダがあって、jQuery自身のテストが納められていたのですが、そこで使われているテスティングフレームワークがQUnitとしてトップレベルのプロジェクトになったようです。

QUnit - jQuery JavaScript Library

これを使うと簡単にjQueryプラグインのテストコードが書けちゃいます。

使い方は以下の通り。

提供されているメソッド

test( name, test ) : nameにテストの名称、testには実行するテストを関数の形で渡します。

module( name ) : テストの途中で、テスト対象のモジュールや関数の目印を付けたいときに使います。nameにはモジュールの名称を渡します。

ok( state, message ) : stateがtrueならOK、falseならNGという判定になります。messageはテスト時に表示するメッセージです。

equals( actual, expected, message ) :actualとexpectedが同値ならOK、異なればNGという判定になります。messageは同上。

expect( amount ) : そのテスト(text(name,test)で引数に指定しているテスト関数)の中で実行されているok()/equals()の数をamountに指定します。テストの数が異なれば、エラーが表示されます。

start( ) : テストを再開します。

stop( ) : テストを中断します。Ajaxで非同期通信等のテストを行うとき、非同期処理前にstop()でテストを止め、非同期処理終了時のコールバック関数内でstart()を実行して、テストを再開します。

サンプル

実際のテストケースを見た方が早いと思うので、以下にQUnitのページで紹介されているサンプルコードを掲載します。

test("a basic test example", function() {
  ok( true, "this test is fine" );
  var value = "hello";
  equals( "hello", value, "We expect value to be hello" );
});

module("Module A");

test("first test within module", function() {
  ok( true, "all pass" );
});

test("second test within module", function() {
  ok( true, "all pass" );
});

module("Module B");

test("some other test", function() {
  expect(1);
  ok( true, "well" );
});

このテストの実行結果はこちらのページで確認できます。

テスト結果の行の最後の3つの数字は、それぞれ「エラー数」「成功数」「テスト総数」を意味しています。

結果の行をクリックすると、各テストのメッセージが表示されます。エラーが発生していた場合は、ここで、どのAssertでエラーが発生したかが分かります。

ということで、上記サンプルをちょっといじって、エラーが発生するパターンのページを作ってみました。

こちらでご確認ください。

equalsでエラーが発生した場合は、期待値と実際の処理結果の値が画面に表示されます。

非常にシンプルなフレームワークなので、さくっとテストを書くことができて便利です。

QUnitの基本的なHTMLは以下のようになります(DLはこちらから)。下記のページに、テストしたいjsを読み込んで、テストコードを書けばOKです。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>QUnit sample</title>
        <script src="http://code.jquery.com/jquery-latest.js">
        </script>
        <link rel="stylesheet" href="http://dev.jquery.com/view/trunk/qunit/testsuite.css" type="text/css" media="screen" />
        <script type="text/javascript" src="http://dev.jquery.com/view/trunk/qunit/testrunner.js">
        </script>
        <script type="text/javascript">
            $(function(){
                try {
                    //ここにテストを記述
                } 
                catch (e) {
                }
            });
        </script>
    </head>
    <body>
        <h1>QUnit example</h1>
        <h2 id="banner"></h2>
        <h2 id="userAgent"></h2>
        <ol id="tests">
        </ol>
        <div id="main">
        </div>
    </body>
</html>

テストケースを、どのように書いたら良いか分からない方は、本家のjQuery自身のテストケースを見てみることをおすすめします。以下にテストJavaScriptコードのリンクをいくつか紹介します。

2008年6月 2日

jQueryでダミーフォーカスの実装

昨日公開した「Amazon ベストセラー ビューア」では、左側の商品のサムネイルで、オレンジ色のカーソルを実装しています。キーボードの、hで左に移動、lで右に移動、jで下に移動、kで上に移動します。

今回は、こうしたダミーフォーカスの実装方法を解説します。

とっても、やり方は簡単で、フォーカスを表現するスタイルシートのクラスを定義して、そのクラスを付け外しするだけです。

Amazon ベストセラー ビューア」では、フォーカスを定義するスタイルシートのクラスとして、以下のようなクラスを定義しています。

#feed img{
    padding:3px;
}
#feed img.selected {
    background-color:#FF8C00;
}

id="feed"のエレメント(サイトではdiv)の下にあるimgは、すべてpadding:3pxとし、selectedというクラスが指定されているimgについては、背景がオレンジ色になります。これで、画像の周りにオレンジ色の枠ができ、フォーカスを表現しています。

以下に、上記スタイルを適用したimgを並べてみます。

selectedクラスが指定された2つ目の画像の周りがオレンジ色になっています。

さて、サイトでは、キーボード操作でフォーカスが移動できるようにしています。

これには、先日紹介したjQueryのキーバインドのプラグイン「js-hotkeys」を使っています。

このプラグインでは、キーに対して、動作させたい関数を以下のように割り付けます。

$.hotkeys.add('Ctrl+c', function(){ alert('copy anyone?');});

では、hキーを押すとフォーカスが左に移動するという機能を実装してみます。

「フォーカスが左に移動する」というのは、以下のように書くことができます。

$('#focus_test_000 img.selected').removeClass('selected')
.prev().addClass('selected');

id="focus_test_000"以下のselectedというクラスが指定されたimgタグから、selectedというクラスをremoveして、そのimg属性の前にある要素にselectedクラスを付加しています。

これをhキーに割り付けるので、以下のようなコードになります。

$.hotkeys.add('h',function(){
    $('#focus_test_000 img.selected').removeClass('selected')
    .prev().addClass('selected');
});

では、動きを見てみましょう。以下に、id="focus_test_000"を指定したpタグの中にimg属性を並べて、上記関数を実行してあります。

hキーを押下すると、オレンジ色のフォーカスが左へ移動していきます。

一番左側にある画像にフォーカスがあたっているときに、hキーを押すと、フォーカスが消えてしまいます。

ということで、先ほどの関数に「一番左側にフォーカスがあるときは、最も右側の(最後の)要素にselectedクラスを付加する」という処理を加えてやればOKです。

さて、フォーカスが移動する要素が少ない場合は、このような実装方法で問題ないかと思いますが、要素が多くなってくると動作が遅くなる可能性があります。

というのも、$('#hoge img.selected') と書いた場合、jqueryの内部では、getElementsByTagNamesでid="hoge"要素以下のimgタグを全て取得し、ループを回してclass名のチェックを行っているからです。

キーボード操作のように、連続して関数が実行される場合は、ライブラリ内部で実行される処理もなるべくコンパクトになるよう考えた方が良いです。

で、「Amazon ベストセラー ビューア」では、左側のサムネイル(imgタグが100個)のフォーカス移動については、selectedIdというグローバル変数でフォーカスが当たっている要素のid属性を管理しています。

つまり、以下のように書くことで、内部ではgetElementByIdが2回実行され、先ほどよりも早く処理することができます。

$.hotkeys.add('h',function(){
    $('#img_'+selectedId).removeClass('selected');
    selectedId -= 1;
    $('#img_'+selectedId).addClass('selected');
});

jQueryの魅力であるメソッドチェーン風の書き方を崩す形になりますが、こちらの方が快適に動作します。

2008年5月26日

jQueryでキーバインド

先日のJUIで刺激を受けて、ちょっとしたマッシュアップアプリを作っているのですが、そこでJavaScriptでキーバインドを実装することにしました。

で、jQueryを使っていたので、適当なプラグインがないかと探してみたら、よさげなのを発見。

js-hotkeys - Google Code

$.hotkeys.add('a', fn);

こんな感じでキーバインドできます。クロスブラウザ対応もちゃんとやっていてくれるみたいです。

デモ・テストは↓こちらで。

デモページ

 

2008年4月18日

Re:一晩で覚えるjQueryの逆引き基礎サンプル7つ

一晩で覚えるjQueryの逆引き基礎サンプル7つ*ホームページを作る人のネタ帳

jQueryに書くとほってんとり入りできるらしいので便乗。というかリンク先で紹介されているサンプルコードにちょっと意義異議あり。

一個のサンプルは非常に単純な構造になっておりますゆえ、jQueryをすでにやったことがある人にとって必要ないものだということをあらかじめご了承くださいませ。

ということであれば、「jQueryらしい」書き方をした方が良いかなと思います。

で、僕ならこう書くってことで。

全般的に使われている$(document).ready(fn)は、$(fn)でショートカットできます。

$(document).ready(function(){alert('hoge');})

は、

$(function(){alert('hoge');})

こう書けると。

まあ、これはどうでもいいや。短く書けるってだけなので。初心者向けに$(document).ready(fn)で説明した方が、「ドキュメントが準備完了になったら」というニュアンスが伝わるのかも。

次に、HTMLとJavaScriptの分離ってことで、サンプルでは、

<input name="btn22" type="button" value="ローディング" onClick="bt01()">
<div id="load1"></div>

と、HTMLのonclickに関数を書いていますが、id属性をつけてJavaScriptのコードで

$('#hoge').click(bt01)

と書くほうがjQueryっぽいのでは。

次に、「閉じる、開くボタンを同一の場所で交互にしたい」というtoggleの処理。サンプルでは、ローディングするHTMLにボタンを書いちゃってますが、これだとメンテナンス性が落ちちゃうんじゃないかなー。

ってことで、

<div id="load1"><input name="btn22" type="button" value="ローディング" onClick="bt01()"></div>

は、

<input name="btn22" type="button" value="ローディング" onClick="bt01()"><div id="load1"></div>

こんな感じにローディングする部分の外にボタンは出しちゃいましょう。あとは、JavaScriptで

$('input[name=btn22]').toggle(
function(){
$("#load1").load("./load.html");//HTMLをロードする処理
$(this).attr('value','閉じる')//自分自身のvalueを"ローディング"から"閉じる"に変える。
}
,function(){
$("#load1").html("");//HTMLを消す処理
$(this).attr('value','ローディング')//自分自身のvalueを"閉じる"から"ローディング"に変える。
}
);

こんな感じかな。長くなって分かりにくくなっちゃったかもね。

あと、jQueryのselectorは,区切りで複数指定できるので、

$(document).ready(function(){
$("#ls1").keyup(function () {
var value1 = $("#ls1").val();
var value2 = $("#ls2").val();
$("#ls3").val(value1 * value2);
}).keyup();

$("#ls2").keyup(function () {
var value1 = $("#ls1").val();
var value2 = $("#ls2").val();
$("#ls3").val(value1 * value2);
}).keyup();
});

は、

$(document).ready(function(){
var calc = function(){
var value1 = $("#ls1").val();
var value2 = $("#ls2").val();
$("#ls3").val(value1 * value2);
}
$("#ls1,#ls2").keyup(calc).keyup();
});

こう書いた方がすっきりするし、同様に

function del(){
$("#ls1").val("");
$("#ls2").val("");
$("#ls3").val("");
}

は、

function del(){
$("#ls1,#ls2,#ls3").val("");
}

と書いた方がかっこゆすだと思います。

jQueryを使ったことない人向けってことだったのだけど、HTMLとJavaScriptを分離できるってところが魅力の一つだし、なるべく短くコードが書けるってところもアピールできたらと思って書いてみました。

別にこれが「正解」ってつもりで書いてないので、あしからず。あくまで僕ならこう書くってことで。

2008/4/18 12:20 追記:

本当にページ中のテキスト入力フォームをすべて空にしたいのであれば、

$('input:text').val('')

でいけます。

あと、jQueryとは直接関係ないかもしれませんが、最後のサンプルで、aタグをcodeタグで囲って、さらにクリックしたときにcodeタグのtitle1,2,3属性とかを持ってくるというのは止めた方が良いですよね。

var clickFunc = function(txt1,txt2,txt3){
  $('#ls1').val(txt1);
  $('#ls2').val(txt2);
  $('#ls3').val(txt3);
}

こんな関数を定義して、各aタグに、

$('a:eq(0)').click(function(){clickFunc('北海道','飛行機','2000')});

とイベントを定義していくかなぁ。まあ、この辺はもっと上手い書き方で来ますね。

2008年4月 2日

jQueryでBASIC認証のAjax通信

最近AIRアプリ(HTML + Ajaxの方)でTwitterクライアントを作ろうと思って色々やっていて、発言を投稿するとかその辺の認証が必要なところはBASIC認証での認証が必要なことが分かりました。

通常のHTMLページであれば、Twitter以外のドメインのページからTwitterのドメインに対してHTTPXmlRequestでAjaxでの通信を試みても、クロスドメインの制約にひっかかってしまうわけです。

ところが、AIRアプリであればこのクロスドメインの制約がなくなるので、通信は成功するはずだったんです。

で、HTTPXmlRequestでBASIC認証するには2通りの方法があって、1つはopenメソッドの引数にユーザIDとパスワードを渡す方法で、もう一つはユーザIDとパスワードをJavaScriptでBase64エンコードを行いAuthorizationヘッダに格納する方法。

JavaScriptのBase64エンコードがちょっと面倒だったので、jQueryの$.ajaxメソッドでBASIC認証の通信ができないものかとjQuery1.2.3のソースを見ていたら、2761行目に、

xml.open(s.type, s.url, s.async, s.username, s.password);

って書いてありました。1.2.1のソースにはs.usernameとs.passwordがなかったので、最近追加されたんですかね。

やったやったと喜んで、これで実装してみたんですが、動かず。

なんでだろ・・・。AIR内蔵のブラウザがこの機能をサポートしてないのかな。うーん。

アーカイブ