htsign's blog

ノンジャンルで書くつもりだけど技術系が多いんじゃないかと思います

またもやブックマークレット作った

初めてコンストラクタ・クロージャに手を出した習作ですが、割と本格的なコードになってきたのではないかなと思ってます。

javascript:(function(){var d=document,s=d.createElement("script");s.type="text/javascript";s.charset="UTF-8";s.src="http://dl.dropbox.com/u/414379/script/BingTranslate.js";(d.getElementsByTagName("head")[0]||d.body).appendChild(s)})()

やってることはシンプルで、小窓を作成。
そこにバーとメインウィンドウをぶら下げ、バーには固定化、最小化、閉じるボタンを、メインウィンドウにはiframeで外部の翻訳ダイアログをはめ込み、Bing Translator APIのお世話になりながら結果を返すというもの。
対応言語は少なめですが、多すぎても見にくいし、何より俺が使うものなので俺中心に設計しています。

もちろん毎度のごとくスパゲティなので、見にくいことこの上ない。
非常に保守性が低そうです。
設計書の大事さを今更理解し始めました。
実装したいことはあらかじめ決めておかないと、拡張拡張また拡張でコードがひどいことになりますね。


小窓生成時の処理は、はてなブックマークブックマークレットを参考にしました。
なんかよく知らんけど、下手に

div#hoge {
  position: absolute !important;
}

って書くより、一旦

div#hoge, div#hoge * {
  position: static;
}

ってした方がいいみたいね。なんでなのこれ。


今回はドキュメントオブジェクトの位置を取得したり大きさを取得したりいろいろやってます。
ドラッグできるオブジェクトというのにも初挑戦しました。
が、HTML部はHTML5で記述した割にHTML5らしいことを何一つやってなかったりします。
まぁ文書宣言で一行書くだけでHTML5になるし、文書のバージョンなんてどうでもいいけど。

めんどくさいからオブジェクトの位置取得はW3C非標準の関数を使っているけど、一応 IE8/IE9/Firefox8/Chrome15 で動いているのでいいです。Opera?なにそれおいしいの?

JSONPでタイムアウトを検知する方法が分からなかったので*1、オブジェクト埋め込みと同時に setTimeout() 関数を走らせ、一定時間反応がなければ通信に失敗したと判断してアラートを出す、という処理にしました(たぶんこの辺バグある)
また、JSONPという仕組み上、GETアクセスなので一度に翻訳できる文章量に限界があります。

今回はビジュアル面にも少々気を使い、通信中は通信中っぽく画像を表示してオブジェクトの上にレイヤー被せる処理をつけてみました。
まぁこれのおかげでだいぶコード増えたりバグだらけになったりもしましたが…。でも個人的には満足いってます。

組んでていつも思うのは、やっぱまだまだ勉強不足だなって。
結局実用的なコードを書こうと思うと、最終的にはprototype.jsとかjQueryとか、そういったライブラリに頼ってしまうと思うけど、そういうのが使えなくても同等のコードが書けるようにはなりたい。


あと、↓これ書いとくだけでだいぶ役に立った。

var addEvent = function (elem, evt, func) {
  if (window.addEventListener) {
    return elem.addEventListener(evt, func, false);
  }
  else if (window.attachEvent) {
    return elem==window
      ? d.attachEvent("on"+evt, func)
      : elem.attachEvent("on"+evt, func);
  }
};

*1:いろいろググったけど無理らしい?