Pure JavaScriptなサイト内検索アプリケーション

ここのところいろいろやっていた、動的にscript要素を追加してクロス・ドメインのJavaSriptファイルを読み込むという手法を使ったYahoo!によるサイト内検索アプリケーション、labs.hail2u.net/yahoo/を作った。Amazon Web Servicesと違い、Yahoo! Search Web ServicesではJSONを出力する機能及びコールバック関数名を指定できる機能(JSONP)を備えているので、HTMLファイル単体で機能するようにすることができた。

といったように、URLのハッシュにドメイン・キーワード・ページ数を指定して検索を行う。

実装において特にややこしいところはなく、コード的にもややこしいところは無いと思う。

強いて言うならページング処理が面倒だったくらい。Yahoo! Search Web ServicesではtotalResultsAvailableで検索結果の件数はわかるものの、実際にはその数まで検索結果として出るわけではないので、総ページ数はわからない(AWSではTotalPagesというそのものずばりなデータがある)。ただ、totalResultsReturnedとリクエストでresultsパラメータとして送った数値(検索結果として返ってくる数)が同じであれば、次のページがあるということは大体わかるので、それを利用すればページングのリンクを作成するべきかどうかは判断できた。Googleのようなページングのリンクのリストを作るのは難しそうだ。

ハイライトはかなりテキトウ。prototype.jsのgetElementsByClassName()each()を使って書いてみた。使ってみたかったから。

また、動的にscript要素を追加してクロス・ドメインのJavaSriptファイルを読み込むという手法のために、

// jsr.js - jsonScriptRequest
//
// This class based on jsr_class.js.
// See Also: http://www.xml.com/pub/a/2005/12/21/json-dynamic-script-tag.html
//
// Copyright (c) 2006 Kyo Nagashima <kyo@hail2u.net>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var jsonScriptRequest = Class.create();

jsonScriptRequest.prototype = {
  initialize: function () {
    this.head = document.getElementsByTagName('head').item(0);
  },

  counter: 0,

  build: function (url) {
    if (!url.match(/\?/)) url += '?dummy=1';
    this.scriptElement = document.createElement("script");
    this.scriptElement.setAttribute("type",    "text/javascript");
    this.scriptElement.setAttribute("charset", "UTF-8");
    this.scriptElement.setAttribute("src",     url + '&nocache=' + (new Date()).getTime());
    this.scriptElement.setAttribute("id",      'scriptid' + this.counter);
    this.counter++;
  },

  add: function () {
    this.head.appendChild(this.scriptElement);
  },

  remove: function () {
    this.head.removeChild(this.scriptElement);
  }
};

というクラスを書いたけど、テキトウすぎるので書き直す。ていうかJSONScriptRequestという名称が気に食わないので、何かちゃんとした名前が欲しい。動的にscript要素を追加・削除するという機能だけを受け持つクラスなので、DynamicScriptElementとかがイメージに近い名前だけど、いまいち・・・。

このサイトのサイト内検索を、labs.hail2u.net/yahoo/をアレンジしたものに置き換えようか・・・とか考えてみたけど、結局このまま。数か月おきにサイト内検索の置き換えは考えているけど、いつもGoogleで良いかなーとかいう結論に。

追記@2006/08/12

とりあえずWeblogの各ページにおいてある検索フォームを差し替えてみた。

追記@2006/08/15

やっぱりGoogle検索の方が良さそう(全サイトからの検索にすぐ切り替えられるし)なので、戻した。Pure JavaScriptなサイト内検索の方はlabs.hail2u.net/yahoo/で試して欲しい。