ログ日記

作業ログと日記とメモ

Google Closure Tools難しい

http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/dialog.html
サンプルのソースを見たら分かるけど、JavaScriptの中にHTMLを書いてる。
Google Sitesでもそうだった。しかも日本語文字列はUnicodeエンコードしてあった。これはClosure Compilerを使ってるからか…。


DBからデータを取ってきてそれをダイアログで表示、とかはどうするんだろう。
最初は単純にテンプレートをAjaxで呼び出してダイアログを表示するのがいいかな。
方向性が合ってるか微妙なところだが。




Debian lenny でClosure Compilerを使うにはまずJavaをインストールする。

java --version
  java version "1.5.0"
  gij (GNU libgcj) version 4.3.2

  Copyright (C) 2007 Free Software Foundation, Inc.
  This is free software; see the source for copying conditions.  There is NO
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

aptitude install sun-java6-bin
update-alternatives --config java
  java-6-sunのjavaを選択

java -version
  java version "1.6.0_12"
  Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
  Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode, sharing)

wget http://closure-compiler.googlecode.com/files/compiler-latest.zip
  展開…


goog.requireでの依存関係を解決しながら最適化レベル最大でコンパイル

DIR=google-closure-library-path
$DIR/closure/bin/calcdeps.py -i input.js -p $DIR -o compiled \
  -c closure-compiler-path/compiler.jar -f "--compilation_level=ADVANCED_OPTIMIZATIONS" \
  > out.js

コンパイラの警告が地味に有り難い。


参考:
http://itpro.nikkeibp.co.jp/article/COLUMN/20091112/340473/
http://code.google.com/intl/ja/closure/library/docs/calcdeps.html

Google Closure Library はフォームを使わない方針?

サンプル見てたらdivとかulとかでコンポーネントが構成されてる。
それはいいんだけど、そっからデータをポストするにはどうしたらいいのか…。


Google Closure Libraryベースで作るってことは、基本全てのデータ送信はAjaxでやるのかな?
Ajaxのやり方は
goog.net.XhrIo: make simple ajax calls with Google Closure – DaveOnCode
ここに書いてある通り。
goog.net.XhrIoを使うらしい。
フォームのデータを取ってくるなら goog.dom.forms.getFormDataMap を使うといい。
しかし通常のフォームとdivで作られたコンポーネントを混ぜるとややこしくなりそうだ。



確かにGoogle Sitesとか管理画面とか見てると、ボタンを押す→「保存中…」→「保存しました」→保存後の画面に遷移したりしなかったり、という流れになっている。
むむむ、そうか…。



あとメモ。
goog.ui.MenuItem系のオブジェクトは、コンストラクタの第一引数がcaptionになって第二引数がvalueになる。
実際はもっと汎用的な引数なんだけど、単純にラベルと値だけ欲しいときは

var menu = new goog.ui.Menu();
var item = new goog.ui.CheckBoxMenuItem('ラベル', '値');
menu.addItem(item);

のようにすればいい。
そしたら後で

if (item.isChecked()){
  var caption = item.getCaption();
  var value = item.getValue();
}

で選択中のデータを取ってこれる。


prototypeっぽい関数

element = goog.dom.$('idName');
valueInForm = goog.dom.$F(element);

javascriptのやっつけAOP

Function.prototype.addAfter = function (callback) {
  var self = this;
  return function () {
    var res = self.apply(this, arguments);
    if (isFunction(callback)) {
      callback();
    }
    return res;
  }
}
http://d.hatena.ne.jp/brazil/20061007/1160157179


頻繁にAOPしない場合はもうちょっと簡単に。やっつけ的な実装をやってみた。

MyObj.prototype.oldMyFunc = MyObj.prototype.myFunc;
MyObj.prototype.myFunc = function(arg){
    this.oldMyFunc(arg);
    aopFunc();
}

var myObj = new MyObj();

汎用的な処理をするほどでもないが、このページだけ処理を変えたいなーというときに。
一カ所で使うだけなら引数の数も固定で。

mixiが使いにくくなっている件

リニューアル?したの?最近PCから全然見てなかったからアレだけども。
mixiが非常に使いにくい。
ぱっと見は「おっ!?」となるかもしれないが、実際に操作してみると細かな点でイライラが。

  • JavaScript盛り沢山なおかげでページを移動するとしばらく固まる
  • コメント書き込み確認の幅や位置が変
  • 自分の最近の日記一覧がなくなっている
  • マイミクシー最新の〜〜がサムネイル画像になっている
  • 色飛ばしすぎ
  • メニュー増えすぎ


数分眺めた感じだとこれくらい。
重いのが一番見る気なくなる。
なので、Sleipnirユーザならばブラウザ右下のデフォルトモードと書いてある部分をぽちっとクリックして一時しのぎ。



最近ニュースサイトも重いよね。
私のPCの性能が低いだけなんかな?
ajaxの弊害だな。技術があるから使えばいいってもんじゃない。自戒の意味も込めて。






いや、自分で作ってるページもjavascriptが少しずつ増えていっていつの間にか激重になってたりするんだよね。
prototype.jsを使っているとやってしまいがちなんだが、observeしまくるとか。
だから今は敢えてhtmlタグの中にonclickやonsubmitを書くことも必要なんじゃないかと。体感速度で結構変わる。

id名重要class名重要

デザイナはサイト全体を通して同じid名や同じクラス名を使う。
プログラマはページ単位で大ざっぱに名前を付ける。


と書いてあったのを見たことがあるけど、割と当たっているような。


スタイルシートJavaScriptを共通化し始めたら、サイト全体が巨大なプログラムのよう。
普段PHPに慣れていると、ページ単位で気軽な名前を付けかねない。
けれど後からデザインとJavaScriptを共通化しようと思うとすこぶる大変だ。


JavaScriptでname属性をキーにした操作をしていると尚更大変。
PHPまで修正する必要が出てくるから。



というわけでせっせこリファクタリング・・・。
テストケースのない見栄えのリファクタリング作業は不安だ。

innerHTML

JavaScriptでだいぶハマってた。
単純な文字列置換でもミスるし・・。Ajaxで取ってきたテキストがIEだとタグ名が大文字になるのね。


あとinnerHTML。
prototype.jsを使うとHTMLElementが拡張されている。
タグには _extended="true" が追加されている。
そのinnerHTMLを取ってきてごにょごにょして表示したりするとエラーになることがある。
innerHTMLでは_extended="true"の文字列はコピーされるけど、ただのテキストなので実際にはprototype.jsによって拡張されたメソッドはコピーされていない。しかしこのテキストをElementに差し込んでprototype.jsの機能を使おうとすると、存在しない関数を呼び出してエラーになる。
innerHTMLじゃなくてDOMで操作すべきなんだな・・ちょっと面倒くさい。