Yahoo!やlivedoorのような検索ボックスを作ってみよう!

what

Yahoo! JAPANlivedoorのような検索ボックスを作りたい。

  • 特徴
    • フォームが空のとき
      • 検索ボタンをクリック場合は検索トップページへ行く
      • チャンネルをクリックしたときは、そのチャンネルをフォーカスする(太字になる)
    • フォームにデータが入っている時
      • 検索ボタンをクリック場合は、フォーカスしているチャンネルについて、フォームデータで検索する
      • チャンネルをクリックしたときは、クリックしたチャンネルについて、フォームデータで検索する


というものである。
検索自体は、検索画面にgetしているだけなので、javascriptだけで実装できそう。


とりあえず結論

dfltweb1.onamae.com – このドメインはお名前.comで取得されています。
↑こんな感じ。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<title>Yahooライクな検索BoxでGoogle検索</title>
</head>
<body>

<script type="text/javascript">
/*
設定
*/
FocusParams = new Object();

FocusParams.WEB_PARAMS = "web"
FocusParams.IMG_PARAMS = "img"
FocusParams.MAP_PARAMS = "map"

FocusParams.WEB_WORD = "ウェブ"
FocusParams.IMG_WORD = "画像"
FocusParams.MAP_WORD = "地図"

FocusParams.WEB_URL = "http://google.com/search"
FocusParams.IMG_URL = "http://images.google.com/images"
FocusParams.MAP_URL = "http://maps.google.com/maps"

FocusParams.DEFAULT_WEB = "<a href=\"#\" onClick=\"focus_unit(FocusParams.WEB_PARAMS)\">"+FocusParams.WEB_WORD+"</a>"
FocusParams.DEFAULT_IMG = "<a href=\"#\" onClick=\"focus_unit(FocusParams.IMG_PARAMS)\">"+FocusParams.IMG_WORD+"</a>"
FocusParams.DEFAULT_MAP = "<a href=\"#\" onClick=\"focus_unit(FocusParams.MAP_PARAMS)\">"+FocusParams.MAP_WORD+"</a>"

FocusParams.FOCUS_WEB = "<b>"+FocusParams.WEB_WORD+"</b>"
FocusParams.FOCUS_IMG = "<b>"+FocusParams.IMG_WORD+"</b>"
FocusParams.FOCUS_MAP = "<b>"+FocusParams.MAP_WORD+"</b>"

/*
デフォルイト値
*/
FocusParams.FOCUS_PLACE = FocusParams.WEB_PARAMS
FocusParams.PARAMS  = "?lr=lang_ja&ie=utf-8&oe=utf-8&q="

/*
フォームの値をセット
*/
function get_search_query(){
  var q=encodeURIComponent(document.focus_search.q.value);
  return q;
}

/*
フォーカス場所セット
*/
function set_focus_place(p){
  if(p){
    FocusParams.FOCUS_PLACE=p;
  }
}

/*
チャンネルのフォーカスをリセット
*/
function reset_foucs(){
  var obj_web=document.getElementById("focus_search_web");
  var obj_img=document.getElementById("focus_search_img");
  var obj_map=document.getElementById("focus_search_map");
  obj_web.innerHTML=FocusParams.DEFAULT_WEB;
  obj_img.innerHTML=FocusParams.DEFAULT_IMG;
  obj_map.innerHTML=FocusParams.DEFAULT_MAP;
}

/*
指定のURLにジャンプ
*/
function jump(p,q){
  switch(p){
    case FocusParams.WEB_PARAMS:
      location.href = FocusParams.WEB_URL+FocusParams.PARAMS+q;
      break;
    case FocusParams.IMG_PARAMS:
      location.href = FocusParams.IMG_URL+FocusParams.PARAMS+q;
      break;
    case FocusParams.MAP_PARAMS:
      location.href = FocusParams.MAP_URL+FocusParams.PARAMS+q;
      break;
    default:
      location.href = FocusParams.WEB_URL+FocusParams.PARAMS+q;
  }
}

/*
フォーカス
*/
function focus(p){
  switch(p){
    case FocusParams.WEB_PARAMS:
      var obj=document.getElementById("focus_search_web");
      obj.innerHTML=FocusParams.FOCUS_WEB;
      break;
    case FocusParams.IMG_PARAMS:
      var obj=document.getElementById("focus_search_img");
      obj.innerHTML=FocusParams.FOCUS_IMG;
      break;
    case FocusParams.MAP_PARAMS:
      var obj=document.getElementById("focus_search_map");
      obj.innerHTML=FocusParams.FOCUS_MAP;
      break;
  }
}

/*
フォーカスして、フォームにデータがあったら検索する。
*/
function focus_unit(p){
  var q=get_search_query()
  set_focus_place(p)

  if(q!=""){
    jump(p,q)
  }

  reset_foucs(p)
  focus(p)
}

/*
検索ボタンを押したときにフォーカスしている場所で検索する。
*/
function focus_search_submit(){
  var q=get_search_query()

  switch(FocusParams.FOCUS_PLACE){
    case FocusParams.WEB_PARAMS:
      location.href = FocusParams.WEB_URL+FocusParams.PARAMS+q;
    break;

    case FocusParams.IMG_PARAMS:
      location.href = FocusParams.IMG_URL+FocusParams.PARAMS+q;
    break;

    case FocusParams.MAP_PARAMS:
      location.href = FocusParams.MAP_URL+FocusParams.PARAMS+q;
    break;

    default:
      location.href = FocusParams.WEB_URL+FocusParams.PARAMS+q;
  }
}

</script>

<form name="focus_search">

<span id="focus_search_web">
  <script type="text/javascript">
    document.write(FocusParams.DEFAULT_WEB)
  </script>
</span> | 

<span id="focus_search_img">
  <script type="text/javascript">
    document.write(FocusParams.DEFAULT_IMG)
  </script>
</span>   | 

<span id="focus_search_map">
  <script type="text/javascript">
    document.write(FocusParams.DEFAULT_MAP)
  </script>
</span>

<br>

<input type="text" value="" name="q" />
<input value="検索" type="button" onClick="focus_search_submit()">

</form>

</body>
</html>

久々にjavascript書きました・・・。



これからは、作成の過程を記します。

フォーカスする

まず、チャンネルをクリックしたときにフォーカスするスクリプトを書いてみましょう。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<title>Yahooライクな検索BoxでGoogle検索</title>
</head>
<body>

<script type="text/javascript">
FOCUS_WEB="<b>ウェブ</b>";

function focus_web(htm){
  var obj=document.getElementById("search_web");
  obj.innerHTML=htm;
}

</script>


<form method="get" action="http://google.com/search">

<span id="search_web"><a href="#" onClick="focus_web(FOCUS_WEB)">ウェブ</a></span> | 
<a href="#">画像</a>   | 
<a href="#">地図</a>

<br>

<input type="text" value="" name="q" />
<input value="検索" type="submit">

</form>


</body>
</html>


とりあえず、これで「ウェブ」をクリックすると「ウェブ」が太字になります。「ウェブ」がフォーカスされましたね。
つづけて、「ウェブ」をフォーカスしたあと「画像」や「マップ」をクリックしてフォーカスできるようにしようと思います。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<title>Yahooライクな検索BoxでGoogle検索</title>
</head>
<body>

<script type="text/javascript">
DEFAULT_WEB="<a href=\"#\" onClick=\"focus_web(FOCUS_WEB)\">ウェブ</a>"
DEFAULT_IMG="<a href=\"#\" onClick=\"focus_img(FOCUS_IMG)\">画像</a>"
DEFAULT_MAP="<a href=\"#\" onClick=\"focus_map(FOCUS_MAP)\">地図</a>"

FOCUS_WEB="<b>ウェブ</b>";
FOCUS_IMG="<b>画像</b>";
FOCUS_MAP="<b>地図</b>";

function reset_foucs(){
  var obj_web=document.getElementById("search_web");
  var obj_img=document.getElementById("search_img");
  var obj_map=document.getElementById("search_map");
  obj_web.innerHTML=DEFAULT_WEB;
  obj_img.innerHTML=DEFAULT_IMG;
  obj_map.innerHTML=DEFAULT_MAP;
}

function focus_web(htm){
  reset_foucs()
  var obj=document.getElementById("search_web");
  obj.innerHTML=htm;
}

function focus_img(htm){
  reset_foucs()
  var obj=document.getElementById("search_img");
  obj.innerHTML=htm;
}

function focus_map(htm){
  reset_foucs()
  var obj=document.getElementById("search_map");
  obj.innerHTML=htm;
}

</script>


<form method="get" action="http://google.com/search">

<span id="search_web"><a href="#" onClick="focus_web(FOCUS_WEB)">ウェブ</a></span> | 
<span id="search_img"><a href="#" onClick="focus_img(FOCUS_IMG)">画像</a></span>   | 
<span id="search_map"><a href="#" onClick="focus_map(FOCUS_MAP)">地図</a></span>

<br>

<input type="text" value="" name="q" />
<input value="検索" type="submit">

</form>


</body>
</html>

これで、「ウェブ」を押したときは、
1.チャンネルをリセットする(デフォルト表示に戻す)。
2.「ウェブ」フォーカスする。
という流れで「ウェブ」をフォーカスします。「画像」や「マップ」も同様です。

これで、「ウェブ」フォーカス時に「画像」をクリックしたときに「画像」のみをフォーカスするようになります。
「地図」も同じですね。


チャンネルをクリックしたら、チャンネルの検索ページにgetする

フォームにデータが入っているとき、チャンネルをクリックしたら、そのチャンネルの検索ページにgetする。
検索はテキストエリアに入っているデータを使って行います。
空のときは、フォーカスするだけの動きです。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<title>Yahooライクな検索BoxでGoogle検索</title>
</head>
<body>

<script type="text/javascript">
DEFAULT_WEB="<a href=\"#\" onClick=\"focus_web(FOCUS_WEB)\">ウェブ</a>"
DEFAULT_IMG="<a href=\"#\" onClick=\"focus_img(FOCUS_IMG)\">画像</a>"
DEFAULT_MAP="<a href=\"#\" onClick=\"focus_map(FOCUS_MAP)\">地図</a>"

FOCUS_WEB="<b>ウェブ</b>";
FOCUS_IMG="<b>画像</b>";
FOCUS_MAP="<b>地図</b>";

function reset_foucs(){
  var obj_web=document.getElementById("search_web");
  var obj_img=document.getElementById("search_img");
  var obj_map=document.getElementById("search_map");
  obj_web.innerHTML=DEFAULT_WEB;
  obj_img.innerHTML=DEFAULT_IMG;
  obj_map.innerHTML=DEFAULT_MAP;
}

function focus_web(htm){
  var q=document.search.q.value

  if(q!=""){
    location.href = "http://google.com/search?lr=lang_ja&ie=utf-8&oe=utf-8&q="+q;
  }

  reset_foucs()
  var obj=document.getElementById("search_web");
  obj.innerHTML=htm;
}

function focus_img(htm){
  var q=document.search.q.value

  if(q!=""){
    location.href = "http://images.google.com/images?lr=lang_ja&ie=utf-8&oe=utf-8&q="+q;
  }

  reset_foucs()
  var obj=document.getElementById("search_img");
  obj.innerHTML=htm;
}

function focus_map(htm){
  var q=document.search.q.value

  if(q!=""){
    location.href = "http://maps.google.com/maps?lr=lang_ja&ie=utf-8&oe=utf-8&q="+q;
  }

  reset_foucs()
  var obj=document.getElementById("search_map");
  obj.innerHTML=htm;
}

</script>


<form method="get" name="search" action="http://google.com/search">

<span id="search_web"><a href="#" onClick="focus_web(FOCUS_WEB)">ウェブ</a></span> | 
<span id="search_img"><a href="#" onClick="focus_img(FOCUS_IMG)">画像</a></span>   | 
<span id="search_map"><a href="#" onClick="focus_map(FOCUS_MAP)">地図</a></span>

<br>

<input type="text" value="" name="q" />
<input value="検索" type="submit">

</form>


</body>
</html>

これで完成です。
フォームのデータは document.search.q.value で取れますので、これを見ればよいですね。


検索ボタンを押したときに、フォーカスしているところで検索する

今度は、「検索ボタン」を押したときにフォーカスしている部分で検索しましょう。フォーカスしていなかったら「ウェブ」で検索することとします。フォームが空の場合も検索します。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<title>Yahooライクな検索BoxでGoogle検索</title>
</head>
<body>

<script type="text/javascript">
FOCUS_PLACE="web"

WEB_URL="http://google.com/search"
IMG_URL="http://images.google.com/images"
MAP_URL="http://maps.google.com/maps"
PARAMS ="?lr=lang_ja&ie=utf-8&oe=utf-8&q="

DEFAULT_WEB="<a href=\"#\" onClick=\"focus_web(FOCUS_WEB)\">ウェブ</a>"
DEFAULT_IMG="<a href=\"#\" onClick=\"focus_img(FOCUS_IMG)\">画像</a>"
DEFAULT_MAP="<a href=\"#\" onClick=\"focus_map(FOCUS_MAP)\">地図</a>"

FOCUS_WEB="<b>ウェブ</b>";
FOCUS_IMG="<b>画像</b>";
FOCUS_MAP="<b>地図</b>";

function reset_foucs(){
  var obj_web=document.getElementById("search_web");
  var obj_img=document.getElementById("search_img");
  var obj_map=document.getElementById("search_map");
  obj_web.innerHTML=DEFAULT_WEB;
  obj_img.innerHTML=DEFAULT_IMG;
  obj_map.innerHTML=DEFAULT_MAP;
}

function focus_web(htm){
  var q=document.search.q.value
  FOCUS_PLACE = "web"

  if(q!=""){
    location.href = WEB_URL+PARAMS+q;
  }

  reset_foucs()
  var obj=document.getElementById("search_web");
  obj.innerHTML=htm;
}

function focus_img(htm){
  var q=document.search.q.value
  FOCUS_PLACE = "img"

  if(q!=""){
    location.href = IMG_URL+PARAMS+q;
  }

  reset_foucs()
  var obj=document.getElementById("search_img");
  obj.innerHTML=htm;
}

function focus_map(htm){
  var q=document.search.q.value
  FOCUS_PLACE = "map"

  if(q!=""){
    location.href = MAP_URL+PARAMS+q;
  }

  reset_foucs()
  var obj=document.getElementById("search_map");
  obj.innerHTML=htm;
}

function search_submit(){
  var q=document.search.q.value

  switch(FOCUS_PLACE){
    case "web":
      location.href = WEB_URL+PARAMS+q;
    break;

    case "img":
      location.href = IMG_URL+PARAMS+q;
    break;

    case "map":
      location.href = MAP_URL+PARAMS+q;
    break;

    default:
      location.href = WEB_URL+PARAMS+q;
  }
}

</script>

<form method="get" name="search" action="#">

<span id="search_web"><a href="#" onClick="focus_web(FOCUS_WEB)">ウェブ</a></span> | 
<span id="search_img"><a href="#" onClick="focus_img(FOCUS_IMG)">画像</a></span>   | 
<span id="search_map"><a href="#" onClick="focus_map(FOCUS_MAP)">地図</a></span>

<br>

<input type="text" value="" name="q" />
<input value="検索" type="button" onClick="search_submit()">

</form>


</body>
</html>

「検索ボタン」を submit から button にしました。buttonを押したときに search_submit() でページをジャンプするためです。 submitの場合 form にセットされている action が使われてしまうからです。こちらで自由にアクション先をセット出来るようにしました。

また、FOCUS_PLACE というグローバル変数をセットしてフォーカスしている場所を記録するようにしました。


日本語対策

フォームの値をセットするところで、エンコーディングすることで対応しました。

/*
フォームの値をセット
*/
function get_search_query(){
  var q=encodeURIComponent(document.focus_search.q.value);
  return q;
}


それでは、リファクタリングしてソースを少し綺麗に見やすくにしましょう。


リファクタリング後のソース

一番最初の結論がリファクタリング後のコードです。


試した環境

OS : Windows XP
ブラウザ : Firefox 3.0.1 , IE6