2007/09/05

少しだけgetElementsByClassNameを効率化。

って、本当に少しだけ。。

getElementsByClassNameは遅いというのは有名な話だけども、少しだけ効率化してみた。って、メッチャ情けない効率化だけども、一応効果はあるんだぜ。IE限定だけどね。私の環境のXPathのないIEではだいぶ速くなったよ。MozillaはそのままXPathにお任せ。

まぁ、getElementsByClassNameにタグも指定できるようにしただけ。つーか、本当にいじったのほんの少し。。。orz
だいたいclass指定は同じ要素にすることが多いと思うんだけど、getElementsByClassNameでは、getElementsByTagNameで全て持ってきちゃっているのね。ここを少しだけ改良しただけ。

  1. document.getElementsByClassNameAndTagName = function(className,
  2. parentElement, tagName) {
  3.  if (Prototype.BrowserFeatures.XPath) {
  4.      return $(parentElement).getElementsByClassName(className);
  5.  } else {
  6.    var children = $(parentElement).getElementsByTagName(tagName || '*');
  7.    var elements = [], child;
  8.    for (var i = 0, length = children.length; i <length; i++) {
  9.     child = children[i];
  10.      if (Element.hasClassName(child, className))
  11.        elements.push(Element.extend(child));
  12.    }
  13.    return elements;
  14.  }
  15. }

えと、他にもprototype.jsのDOM操作はヤヴァイね。下手に使うと遅すぎ。。。next, previous, up, downとか。。。どこかにも書いてあったけど、引数を付けるとダメダメ。付けなくてもダメだけど。。まぁ、最初はカッコよく書くためにprototype.jsで書いて、それから効率化するときに適当にnextElementとかの自分用メソッドを拡張なんかしちゃったりして、重そうな処理を削れば結構快適になるがいいかもね。

最近はファウラーのリファクタリングを読んでいるけど、最初からうまく行く設計なんてないよねー。全く何もないところからはさすがに無理だと思うけど、思いついたらその都度設計を変えていけばいいと思うんだよね。で、今回はリファクタリングを結構していたため、パフォーマンス改善周りもやりやすかったのは感激。

しかし職業としてプログラミングをしていると、構造の正しさ、美しさやアルゴリズムよりも、泥臭い対応の方が現実的だったりするのが、なんというか、そういうのちょっと嫌。

2007/08/24

IEでElementのメソッドがextendされない件について(script.aculo.us-1.7.0)

最近は、激しくJavaScript。いやー。setTimeoutが使いこなせないので、まだまだなのだけども、勉強しながらやっているっす。つーか、最近はまったのよ。Elementがextendされない問題についてね。あ。ちなみにIEのみね。でも、IEで問題があるサイトなんて使えないので、結構大事だと思う。

その件について、いろいろ悩んでググッていたら、[javascript,prototype]innerHTMLに +=(文字列結合)するのはよろしくないみたいのサイトを発見したのだけど、まさしくこの状態。つーか、結構前のポストだし解決されたんだ、と思ってscript.aculo.usの中に入っているprototype.jsを見てびっくり。1.5.0じゃねーか。つまり、未解決状態。。。まぁ、私は文字列結合していないんだけど、問題があったけどね。同じ要素オブジェクトを削除したり、追加したりしているのが問題だったみたい。バグフィクスにもそんなようなメッセージになっているので。

Changeset 6385

Make Element.extend work on IE for Nodes with the same ID that where discarded.

えと、このバグフィクスは、1.5.1_rc2で解決されているんだけども、だいたいprototype.jsはscript.aculo.usと一緒に使うので(って私だけ?)、問題が残っているんだな。上にも書いたようにscript.aculo.usのバージョン1.7.0(現時点の正規版)に入っているprototype.jsは1.5.0なので。速く次のバージョンでないかな。ってか、ベータ版を使えば、この問題はないので、それでいいのかも。つーか、できれば正規版のバージョンを上げて欲しい。

で、この問題を解決するには、Element.extend doesn't seem to work in IE sometimesにも書いてあるように上のChangeset 6385のリンクに書いてあるようにするか、ベータ版を使うか、どちらか。

Prototype and script.aculo.us

そういえば、今回の件でscript.aculo.usについて調べていたら、こんなe-bookが出ているらしい。欲しいにょ。まだベータみたいだけど、$22なら買いかなー。つか、うちのPC壊れているので、今買ってもなんかなー。と言っている間に一年くらい過ぎそうのだが。。。うん。もう少し様子見よう。7章と8章でも読んで買うかどうかを決めようっと。まだまだ勉強が足りないっす。

2007/08/15

YUI Theaterイイ!

ちょっと前にブックマークしておいたYou think you know (JavaScript) but you have no ideaのビデオを見ていたのだけど、この講義はイイ。復習にイイ。しかも、英語の勉強になる。私にはちょうどいいレベルでこのくらいだったらほぼ何を言っているか理解できる。

いきなり「おはよう。ようこそ、ブレアウィッチプロジェクトへ」って外しているところがなんとも良いね。そこで、Douglas Crockford氏のファンになってしまいました。彼のビデオは、YUI Theaterにいくつか上がっているみたいなので、YUI Theaterを毎日一つずつくらい見ようと思う。

明日は、これを見よう。ktkr約50分。。。
Douglas Crockford — "Quality"

Yahoo! JavaScript Architect Douglas Crockford provided the anchoring keynote for Yahoo!'s annual internal web-development conference in March, 2007. The subject of the talk is "Quality" — the processes by which we engineer quality into our software and, of course, the processes by which we often fail to do so.

というわけで、自分の英語力も試してみたくなったので、TOEICでも受けてみることにする。ついでにスピーキングとライティングも見ることができるものもあるみたいなので、そちらも受けてみる。学生の頃、受けたときがパーセンタイルで80%くらいだったので、それよりもは上がっているかな。まぁ、仕事には全く関係ないけどね。。。まぁ、エゴですよ。エゴ。

2006/11/12

Sjaxを使ってみた。

実は、会社を辞めてからの方が忙しい。。。会社にいたときは、「会社での仕事をする」という正統な理由があったため、ずっと後回しにしていたTODOが溜っていたのだ。で、最近は、ずっと家にいるので、溜ったTODOをこなすのに、ヒーヒー言っている。

最近は、ほとんどJavaScriptしか書いていない。もしかしたらPHPよりも得意な言語かもしれないので、まぁ、いいのだが、結構いっぱいいっぱい。

で、最近、Ajaxで受け取った結果を非同期ではなく、同期で次の処理に使いたいときがあった。つまり、Asynchronousではなくて、Synchronousなので、Sjaxか。って、ちゃんとそういう言葉があるんだね。

Sjaxとは - はてな

私の理解が正しければ、単純に、Ajax.Request(すでにprototype.js前提)のoptionsにasynchronous: falseって書くだけだけどね。

Ajaxの場合は、onLoadingとかonCompleteのイベントにゴニョゴニョ書いて返ってきたデータをよろしく加工しちゃったりするわけだが、まぁ、普通にこんな感じ。

new Ajax.Request(
  url,
  {
    method: 'get',
    parameters: $H({'par1': "parameter1desu", 'par2': "parameter2desu"}).toQueryString(),
    onComplete: function(request) {
       // request.responseTextをゴニョゴニョしちゃうの。
       alert(request.responseText);
    }
  }
);

Sjaxの場合は、Ajax.Requestオブジェクトのtransport.responseTextで受け取ったものをゴニョゴニョするって感じ。

var ajax = new Ajax.Request(
  url,
  {
    asynchronous: false, // デフォルトはtrueなので、指定しないとAjaxとなる。
    method: 'get',
    parameters: $H({'par1': "parameter1desu", 'par2': "parameter2desu"}).toQueryString()
  }
);
// ajax.transport.responseTextをゴニョゴニョしちゃうの。
alert(ajax.transport.responseText);

つーか、onCompleteとかonLoadingとかって書いてみたけど、何もしてくれないのね。まぁ、synchronousだから当然だけども。

確かに「Sjaxとは」にも書いてあるように、メリットは、結果をそのまま次の処理で使えちゃうことかな。まぁ、その間、同期なので、止まるけど。でも、ある関数内で、Ajax.Requestなどの結果を修正して返したいときなんかは便利だよね。イベントにそのまま渡して、非同期に処理を実行して終了するものだったらいいけど、それから先にまだまだそのデータを使いたいときとかにね。

私は、どうしても同期をとりたいときがあるんだけど、どうしたらいいのかなー、なんて考えて、フラグを立ててそれを見張るか?とか考えたんだけど、Sjaxでいいのね。

2006/09/22

contenteditableの挙動がクソな件について

最近、仕事でcontenteditableの挙動に苦しめられている。

contenteditableと言えば、IEで使える編集可能なdivと言ったところか。あと、よろしくexecCommandとかやってあげると、タグを付けてくれたりしてくれる。Mozillaの方で同じようなことをするには、designmodeとかあるらしいのだが、それは使用していない。今作っているのが、IE限定なので。

そのため、IEの挙動をチェックしなければいけないので、まず、普段使っている開発環境をWinにしなければならない。その時点でかなり萎える。そして、contenteditableの中でいろいろすると、やってほしくないことまで勝手に補間されてしまうのだ。

世間一般にあるwysiwygHTMLエディタに、TinyMCEや、FCKeditor、DojoのRich Text Editorとかあるんだけど、どうも嫌だ。wordpressにもデフォルトでTinyMCEが入っていたが、速攻外したし。でも、まぁ、普段ブラウザはfirefoxを使っているから、まだいいのだが、IEの挙動は許せん。

改行すると勝手にPタグを突っ込むので、イベントを見張って、BRタグに変更してあげたり、まぁ、めんどくさいことをいろいろしていたのだが、今回の挙動については激しく鬱になる。
それは、勝手にハイパーリンクを補うことだ。
例えば、shin@homeとか書いたりすると、勝手にメールアドレスと判断して、mailtoのハイパーリンクをつける。同様にhttp://hogehogeとかしても、ハイパーリンクとなる。まぁ、後者のhttp://から始まるのはある程度しょうがないかなーなんて思っているわけだが、shin@homeを変えられるのは嫌だ。メールアドレスとして判別するならば、もう少しマシなチェックをしてもらいたい。ちゃんとその文字列がメールアドレスか正規表現であるでしょ、と小一時間。。。まぁ、これも見張っていて、mailtoのハイパーリンクが来た途端、取り除くってすればいいのかな。他の有効なハイパーリンクとの違いとかを考慮しないといけないので、面倒だけど。

で、実は、フルスクラッチで書いている私が馬鹿で既存のライブラリを使ったら行けるかな、と思って、TinyMCE、FCKeditor、DojoのRich Text Editorを使って実験してみた。Mozillaは問題なし。IEは同じところで勝手にハイパーリンクとなる。もう、これだけメジャーなライブラリがこれなら、拘らなくていいような気がしてきた。しかし、この挙動はウンザリで、contenteditableなんて使いたくないと心から思ったさ。

というわけで、考えていたら、今日少しアイデアが出た。Flashで作ればいいんじゃないの?contenteditableを使用し、自分が制御できないところがあるのが問題なわけで、Flashでやったら、全部制御できるwysiwygエディタが出来そうな予感。実は私は、ActionScriptを昔よく書いていたので、いけるかもしんない。2年ほど書いていないので、ブランクはあるが。。時間があるときにやってみようかなー。いかん、他にやらんといかんことがまだまだある。

Flashでのwysiwygっぽいツールとしては、NOTAというのがあるけど、もう少し構造的なHTMLを書けるものがいいなー。NOTAは、HTML表示するとposition指定をしているって感じで、見た目重視な感じがするので、ちょっと違うって感じがする。あ。でも、DojoのRich Text Editorのチュートリアルに書いてあるように、WYSHASMWMOMNBWYGなんてユーザは考えてねーよ。ってことなので、私のこの考えは逆流しているかもしれない。。。

というわけで今日初めて、WYSHASMWMOMNBWYGという言葉を知りました。"What You See Has A Semantic Meaning Which May Or May Not Be What You Get"の略だって。なげーよ!

2006/07/29

Prototype Window Classをもう少し使ってみるテスト

Services_YouTubeのサンプルを作る際に使用したPrototype Window Classをもう少し使ってみた。以前、こういうの作りたかったんだよなーなんてのが結構簡単にできそう。アラートなんかも結構快適かも。

Prototype Window Class

ただやっぱりWindowの中にYouTubeのswfファイルを使用させるのはかなり重くなりそう。

で、こんな感じか。

Open Window

  • default
  • mac_os_x
  • spread
  • nuncio
  • darkX
  • alphacube
  • theme1
var win; var id = 0;
function openWindow(className) {
win = new Window('window_id' + id, {
className: className,
title: "Sample",
width:200, height:150}
);
win.getContent().innerHTML = "<h1>Hello World!</h1>";
win.setDestroyOnClose();
win.showCenter();
id++;
}

Open Alert

  • sample
function openAlert() {
Dialog.alert("Hello World!", {
windowParameters: {width:300, height:100},
okLabel: "close",
ok:function(win) {debug("validate alert panel"); return true;} });
}

Services_YouTube

var win;
function openVideo(video_id) {
if (win == undefined) {
win = new Window('window_id', {
className: "dialog", width:445, height:370, zIndex: 100, resizable: true, title: "Sample window", showEffect:Effect.BlindDown, hideEffect: Effect.SwitchOff, draggable:true });
}
win.getContent().innerHTML= '<div style="padding:10px"><object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/' + video_id + '"></param><embed xsrc="http://www.youtube.com/v/' + video_id + '" type="application/x-shockwave-flash" width="425" height="350"></embed></object></div>';
win.showCenter();
}

--

つか、ちゃんと動くかな。 やっぱり、UIがカコイイといいねー。

2006/06/16

Javascriptライブラリ比較

JavaScriptのライブラリの比較についてまとめをdel.icio.usで発見した。ちょっと興味があったので、少しだけまとめておく。
http://www.sitepoint.com/article/javascript-library/2

ここのサイトで取り上げられているのは、次の4つ。

  • Dojo
  • prototype.js + script.aculo.us
  • Mochikit
  • Yahoo! UI Library

なかなかまとまっていて私もだいたいわかった。
実際に使ったことがあるのは、prototype.jsとYUIだけだったけども、著者はMochikitが良さそうってことを書いている。まぁ、もちろんどんなところに使うかによって使うライブラリを分けようって話だったけども。

Dojoは、巨大なライブラリだ。だいたいの機能がそろっていて大規模なJavaScriptアプリを書くに向いている。そのため、ライブラリのファイルサイズも使うことのできるAPIも大きいので、小さなプロジェクトにはおすすめしない。

prototype.js + script.aculo.usは、ドキュメントが一番成熟している。(私の認識と違うけど、最近ドキュメントが充実してきているのかな。。。)そして、現時点で一番広まっているライブラリである。Rubyのイディオムに似ているので、Ruby開発者には問題なく使える。また、Railsで使われているので、バグフィックスとかもはやくていいとのこと。他にもscript.aculo.usやRicoのようなライブラリに使われているので、多くの開発者の選択肢の一つとしてあげられている。でも、イベントハンドリングにおいては、他のライブラリに劣っている。

Mochikitが一番よく設計されていていて、Pythonのイディオムに似ているため、Python使いは問題なく使える。ただ、ドキュメントが足りないと見受けられる点もあって、ちょっと混乱するかもしれないところはイケてない。でも、使い慣れたら、びっくりの連続だ。DOM周り、イテレーション、Ajaxなんて芸術的だぜ。

YUIは、prototype.jsを使うまでもない小さなプロジェクトに向いているとのこと。Ajax、イベント周りの使用方法を簡単に学べるところが魅力だとこと。でも、全体としていかした機能は少ない。

一時期YUIっていいねぇ、と思っていたけど、そうでもないのかな。個人的な意見としては、YUIは、YUIデザパタの実装方法をAPIとして提供したら、一気に評価があがると思う。いつかも書いたけども、Yahoo!は、今までのインターネットポータルサイトを支えてきたサイトなので、UIのノウハウがいっぱいあると思うんだよね。だから、あそこで提唱しているデザパタってかなり使えると思う。現時点では、実装するためにかなり力業を要しないといけない気がするので、私は手をつけていない。APIとして、あのデザパタを提供してくれることを望みます。あまりにも遅いと他のライブラリがそれをAPIとして作ってしまうと思う。

後、最近、symfonyを勉強してたけど、あれもprototype.jsを使っているね。フレームワークとの相性って普及するかどうかって大事だと思うので、prototype.jsがやっぱりいいのかなぁ、なんて思ってみたりもする。

2006/06/13

Seleniumがかなり良さげ。

テストツールをいくつか見てみたけども、Seleniumは、ページのシナリオテストに持ってこいだね。かなり便利。Selenium最高!後は、これをうまいことドキュメントに落とすことができるものがあればいいんだがなぁ。

会社では、テスト仕様書などを結局ドキュメントでエクセルか何かで欲しいと言われるので、Seleniumのテストケースでは受け入れてくれない。なので、特定のXMLもしくは、YAMLからSeleniumのHTMLテーブルを作成するってのがあったらいいなぁ。そして、そのXMLかYAMLから印刷可能な形式にしてドキュメントにしちゃうの。そして自動化。個人的にはPDFで吐いてほしい。

もしくは、すでにあるHTMLのテーブルから適当にパースして、マネージャの人が納得するドキュメントを作成できる機能がいいよね。

まぁ、テストやそのドキュメント化の作業はできるだけ自動化してしまいたいので、Seleniumは本当にいい。つーか、気づくの遅いな、ヲレ。
(続きを読む...)

2006/01/21

AjaxのonCompleteの処理は、サブクラスに任せる。

そんなことをやってみたので、簡略化して、載せてみる。
で、ファイルは以下のような感じ。面倒なので、全部同じディレクトリにしてみた。
HTMLファイルを見れば、わかるが、prototype.jsを読み込んでから、sample_ajax.jsを読み込む。
おそらく、世間一般に広まっているprototype.js1.3.1では、動かない。まぁ、そんな感じ。

サンプルは「ここ」のページにあります。

  1. sample_ajax.js(下のソース)
  2. prototype.js(1.4.0)
  3. HTMLファイル(sample_ajaxhtml)
  4. Aの読み込み
  5. Bの読み込み

sample_ajax.js

var AjaxParent = Class.create();
AjaxParent.prototype = {

    initialize: function() {
        alert("サブクラスでちゃんと実装してね。");
    },

    /**
      * pathにリクエストを出して、読み込みが終わったら、completeメソッドを呼ぶ。
      *
      * @param path : リクエスト先なのだ。当然のことながら、同じサーバのみね。
      */
    get: function() {
        new Ajax.Request(this.path,
            {
                method       : 'get',
                onFailure    : function(request) {
                    alert("ネットワークへの接続が失敗しました。");
                },
                /** 最後にbindAsEventListenerをちゃんとつけること。 */
                onComplete   : function(request) {
                    var result = request.responseText;
                    this.complete(result);
                }.bindAsEventListener(this, false)
            });
    },

    /**
     * 親クラスでは、誰が何と言おうが、holderは、id=result_pである!
     */
    set_holder: function(holder) {
        this.holder = $('result_p');
    },

    complete: function(result) {
        alert("サブクラスで、ちゃんと実装してね。");
    }
}

/**
 * AjaxParentクラスのサブクラス。
 */
var AjaxChild_A = Class.create();
Object.extend(AjaxChild_A.prototype, AjaxParent.prototype);
Object.extend(AjaxChild_A.prototype, {

    /**
     * 子クラスでinitializeを上書き。
     */
    initialize: function(path) {
        this.path = path;
        alert("AjaxChild_A initialized....");
    },

    /**
     * フィールド
     */
    field: "this is field From AjaxChild_A",

    /**
     * 子クラスで、set_holderを上書き。これは、AjaxChild_Aのみ。
     */
    set_holder: function(holder) {
        this.holder = $(holder);
    },

    /**
     * 子クラスで、completeを上書き。
     * @param response
     */
    complete : function(result) {
        new Insertion.Top(this.holder, "AjaxChild_A: " + result + "<br />");
        alert("AjaxChild_A : " + result);
    }
});

/**
 * AjaxParentクラスのサブクラス。
 */
var AjaxChild_B = Class.create();
Object.extend(AjaxChild_B.prototype, AjaxParent.prototype);
Object.extend(AjaxChild_B.prototype, {

    /**
     * 子クラスでinitializeを上書き。
     */
    initialize: function(path) {
        this.path = path;
        alert("AjaxChild_B Initialized....");
    },

    /**
     * フィールド
     */
    field: "this is field From AjaxChild_B",

    /**
     * 子クラスで、completeを上書き。
     * @param response
     */
    complete : function(result) {
        new Insertion.Top(this.holder, "AjaxChild_B: " + result + "<br />");
        alert("AjaxChild_B : " + result);
    }
});

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
 * createの引数typeによって、どちらの子クラスを呼ぶかを変える。
 */
var AjaxController = Class.create();
AjaxController.factory = function(type, path, trigger) {
    var my_ajax = eval('new AjaxChild_' + type +'("'+path+'")');
    Event.observe($(trigger), 'click',
                  my_ajax.get.bindAsEventListener(my_ajax), false);
    return my_ajax;
}

sample_ajax.html

<?xml version="1.0" encoding="shift_jis"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="ja" xml:lang="ja" xmlns="http://www.w3.org/1999/xhtml">
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript" src="sample_ajax.js"></script>
    <script language="JavaScript" type="text/JavaScript">
Event.observe(window, 'load', main, false);

function main() {
    /**
     * インスタンスを作ってやってみよう!
     */
    var ajax_test = AjaxController.factory('A', './test_a.txt', 'trigger_a');

    /**
     * ちゃんと子クラスのフィールドにもアクセスできる。
     */
    alert(ajax_test.field);

    /**
     * 同様に、メソッドにもね。
     */
     ajax_test.set_holder('result_a');

    /**
     * インスタンスを作ってやってみよう!
     */
     var ajax_test = AjaxController.factory('B', './test_b.txt', 'trigger_b');

    /**
     * ちゃんと子クラスのフィールドにもアクセスできる。
     */
     alert(ajax_test.field);

    /**
     * メソッドは実装していないので、親のが呼ばれる。
     */
     ajax_test.set_holder('result_b');
}
  </script>
    <title>Ajax Subclass Test</title>
  </head>
  <body>
    <h1>Ajaxのテスト</h1>
    <input type="button" id="trigger_a" value="Ajax_A!" />
    <input type="button" id="trigger_b" value="Ajax_B!" />
    <hr />
    <h2>AjaxChild_Aが実装したのでこっち。</h2>
    <div id="result_a"></div>
    <h2>AjaxChild_Bは未実装なのでここは出力されない</h2>
    <div id="result_b"></div>
    <h2>AjaxParentのメソッドのままだが、AjaxChild_Bは未実装なのでこっち。</h2>
    <div id="result_p"></div>
  </body>
</html>

気になるところは、コメントに書いてみた。onCompleteにbindAsEventListenerをつけないと、thisの値が変わってしまう。これで、一度悩んだ。。。
拡張するときに、プロパティを書き換えるのもなんだか、嫌だけど、しゃーなし。

参考にしたのが次のページ。

IT戦記

 拡張の方法はここを参照させていただきました。prototype.jsと少し拡張の書き方が違うが、やっていることは一緒。prototype.jsでは、次のようにしていたりする。

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {

naoyaのはてなダイアリー

 ここを見て、動的にクラス名を決定するところで、evalを使うようにした。次のような感じ。

 var test_class = eval('new ' + classname);

llameradaの日記

こども(てれび)

 上の二つを見て、thisがどっかいっちゃうところを修正した。AjaxのonCompleteにbindAsEventListenerをくっつけるところは、ここで、勉強しました。

Using prototype.js v.1.4.0

 1.4.0を対象にしていたので。
(続きを読む...)

2006/01/11

少しばかりAjaxな辞書ツール作った。

英辞郎に飛ばすBookmarkletとかあるけども、あまりページを遷移したくないなぁ、という風に前から思っていた。

だって、何かの文章を読んでいるときに、一つわからない単語があって、Bookmarkletで訳を見るまではいいけども、その前の文章に戻ってきた際(戻るのもウザイ)、どこを読んでいたかわからなくなることがよくある。なので、ページの中に訳が出てきたらいいなぁ、なんて思ってみる。

Google Toolbarのマウスオーバー辞書ってのもあるんだけど、なんかひっかからないのが多くてちょっと嫌。イメージでは、こんな感じなんだけどなぁ。で、何かないかなぁ、と考えていたが、調べてもないので、ブログをやり始めた頃に考えていたものを自分で作ってみることにした。

仕組みは簡単なので、誰でも簡単に作ることができると思うけど、なんで無いのかなぁ。ドイツ語と英語のやつはあったのに。ということでおうちでプログラミング。まぁ、作るのめんどくせーな、と思ってたけども、少しだけやる気になってみた。まぁ、perlのお勉強ですわ。

で、作ったものが、Ajaxな英和/和英辞書。
って、別にAjaxでなくても、ボタンでポチットな、でよかったのだが。prototype.jsでも使ってみるか、と思っていてせっかくだったので、Ajaxな動きを取り入れてみた。

辞書ファイルは、EDICTを使用した。xyzzyでは、私も使っているけどもいい辞書ですね。そして、その辞書の検索には、私の学部時代の師匠が作った検索システムDiqtを使用させていただいた。で、それを学校の研究室のサーバにインストールをした。Diqtサーバは、そのまんま。XML RPCサーバにしてもいいかな、と思ったけどもとりあえず、自分のためだけのツールということでいじることは辞めた。気が向いたらするかも。

で、処理としては、JavaScriptで網掛け部分を取得し、マウスアップしたら網掛け部分をパラメータとしてリクエストを飛ばす。そのリクエストを受け取るサーバ(Diqtサーバのクライアント)は、受け取ったパラメータを加工して、DiqtサーバにHTTPリクエストを投げる。Diqtサーバからのレスポンスを、また少し加工して、JavaScriptのリクエストに対するレスポンスとして返す。そして、そのレスポンスを表示したい場所に入れる、と。

これで、網掛けに選択した言葉を瞬時に同じページに出力することができた。Ajaxの使用用途でこれは、間違ってないかな。あまり鬱陶しいインタフェースは使ってないし。ただ、リクエスト飛ばしすぎになってしまうのではないか、とちょっと思ってみる。

で、早速、このツールを自分のブログに当てはめてみる。どこでもいいが、選択すると、もし選択した単語に対応する訳があれば、それを右のメニューのDYNAMIC DIQTの下に出力する。半角英数を選択すれば、訳は日本語で。日本語を選択すれば、訳は英語が出るようにした。まぁ、悪くないね。もう少し整理したら、簡単なやり方とサンプルを MY WORKに置こうかな。

つか、なんで、Diqtサーバが別の環境を使っているかというと、今のレンタルサーバでは、容量50Mだし、Cで書かれたCGIスクリプトとか動かないだろうから。別にサーバに余裕があって、いろいろインストールできるのだったら、同じサーバでもいいか。

うーん。でも、こんなもの作りなんてすぐ終わっちゃうよね。もう少し規模の大きめなものを作りたいなぁ。
まぁ、CPANのLWP, TokeParserの使い方を勉強したから、これはこれでいいか。

つか、絵を描かないと、文章だけじゃ何を言っているかわからんかな。
(続きを読む...)

Bloglines feedburner