Code

2013年12月15日日曜日

Web App : Event driven デザイン、ほかいろいろ

 JavaScript という言語は Event Driven です。マウスでウェブページをクリックすると、 click イベントが発生します。ブラウザは各イベントキャプチャーして、各要素にバインドしたイベントハンドラを呼び出します。イベントハンドラにわれわれは DOM 要素や CSS クラスを追加したり、外したりすること、ウェブページが動的になります。
 これは一般的な Web App のデザインです。それで、jQuery(document).ready(function() {}) みたいな関数が大変重要になります。なぜなら、ブラウザが HTML をパースしている間、クローズタグを終える前に、JavaScript でその中の要素を操作すると、エラーになって、ウェブページも変な形になります。このようなエラーはよく IE で見かけます。
 (実は jQuery ready 関数が onLoad などの Native 関数のラッパーだけです。いろんなブラウザ実装が違うため、最後にいつウェブページがロード終わったかちょっと違います。このような違いがなくすことで、私たちは一つのコードすべてのブラウザを対応できるようになります。Selector 機能と同じように、Cross browser も jQuery の一つ大きな特徴です。)
 このような Web App は簡単に設計できます:
一般的に、HTML を書いて、CSS クラスで色や display 属性を定義して、ready() 関数に対象の DOM 要素に初期化処理やイベントハンドラを定義することだけです。例えば:
<!DOCTYPE HTML>
<HTML>
  <HEAD>
    <script>
       $(document).ready(function() {
              // DOM のロードが終わったら、すべてのボタンと A tag に click イベント
              // ハンドラをバンドします。
             $('button, a').click(function(event) { console.log($(event.target).tagName); }
        });
    </script>
  </HEAD>
  <BODY>
    Sample です。
     <button type = "button" value="Hello"></button>
     <a href="#">Link</a>
  </BODY>
</HTML>

 ただ、このような Web App メンテナンスはちょっと大変です。なぜなら、他の開発者は「この機能はどのように実装したか」を探し出すことが面倒ですし、イベントハンドラはそう簡単に見つからないこともよくあります。JavaScript の特徴で、ただの検索だけで、見つからない可能性が十分あります。
 あと、すべての要素は一つのコードでコントロールできるので、その一行のコードを見つかるには、ちょっと時間がかかるかもしれません。
 もう一つの問題は HTML には状態など記録する機能は従来ないので、CSS や属性などを我々直接操作するしかありません。
 このような問題を解決するために、いろんなライブラリが出てきました。逆に、Event Driven もいいところが結構ありまして、これもnode.js 売りになっています:ブロックがないから、サーバーとかはいつでも、莫大なリクエストが処理できるようになります。

 knockout.js などちょっとしたライブラリの着目点もここにあります。HTML に自ら定義した属性を追加して、イベントハンドラや、初期化などのコードを HTML で見えるようになります。
 次に Backbone.js, AngularJS, Ember.js など MV* Framework が他の道で Web App の開発を簡単にできるようにします。
 だから、Frame work を使おう。:) 世界が綺麗になります。

2013年12月11日水曜日

AngularJS コンセプトから

 最近 AngularJS Frameworkを勉強しながら、web app を作っています。jQuery や、backbone.js, ember.js, knockout.js などのライブラリと違うタイプで、使いこなすまで、ちょっと時間がかかるかもしれません。ember.js もそうですけど。。。
 ただ、ある程度慣れると、開発のスペードは結構あがりますので、損はないでしょう。

 コンセプトから:
 jQuery は 主に DOM を操作するためのライブラリで、AngularJS は MVVM の Framework です。ライブラリは Function を呼び出すことで、機能を実現しますが、 Framework だと、"Don't call me. I will call you." 式になります。つまり、自分は部品を提供して、Framework がそれを呼び出して、機能を実現します。
 AngularJS をがロードされるとき、まず ng-app という directive を探して、compile されます。されに、その下のすべての ng- から始まった core directive や、自分で登録した directive をスキャンされて、scope を作ります。その後、controller が初期化されて、このとき、controller にあった model, viewModel が初期化されて、link されます。すると、ウェブページが表示されるようになります。
 この過程はかなり複雑ですし、各 directive も違うし、操作 Queue の作りも簡単ではありません。こちらのコードは今まで読んだ JS code の中で神様の領域に入るような気がします。:)まぁ、結構かみコードは結構ありますけど。
 通常の DOM 操作より、AngularJS は two-way data binding で Developer を複雑、面倒なデータアップデート処理から解放して、機能やアーキテクチャーに集中させるようになります。
 
さらに、$injector で Dependency Injection を他の Framework から導入されます。そうすると、Unit test や automatic integration test も大変簡単になります。例えば、service に provider, factory を定義して、違うデータソースからデータを取得して、上の Controller がそれに何も知らなくても、ただ関数を呼ぶだけなので、レイアの Decoupling が実現されました。

あと、$filter や、directive も自分で定義できるし、ng-include で template のサポートもできます。handlebarsよりわかりやすいし、機能的にはかなり面倒な、簡単な部分をカバーしています。

まぁ、一般的な Web App だったら、 jQuery が十分だと思いますけど。例えば、ボタンで表示部分の変更、Drop down リストの変更などは AngularJS を使うより、jQuery のほうが速いし、簡単です。underscore.js などのライブラリと一緒に使うと、便利です。
もし、データ操作の多い、データによる画面更新の多い Web app だったら、Angular.js を使ったほうが遥かに開発効率があがります。特にbootstrap と一緒に使うとき。

 私は以前他の js library を使ったことも結構ありますが、 AngularJS は開発思想から違うので、Think in AngularJS が必要ですね。また後日で。

 それでは。

Cross-browser CSS バグなどいろいろ

 CSS なんで、たまに難しいですな。IE はそのように表示して、Firefox と Chrome はあのように表示するかはなぞなぞです。 orz
 ただ、今まで、わかって来たことは Chrome は一番 HTML 標準を準じているとのことです。 Firefox も結構いいですが、たまにこれはちょっと違うなと思われます。
 バグなおしの経験:
1 IE 6, 7, 8 である要素をクリックすると、ブラウザの画面が下または上に飛ぶ。
 これは大体クリックされた要素の position は relative か、absolute で、しかも親要素の position は何も設定されてないためです。
 要素の position は「初めて position は static ではない親」の位置から決めます。もし親要素の position が設定してなかったら、デフォルトは static になります。そうすると、ブラウザは上まで一つ一つ探して、body まで見つからなかったら、body の位置を参照して、要素の位置を決めます。
 そうすると、ある position 設定されている要素をクリックすると、もし親の position が何も設定されてなかったら、 body の位置と参照して、ブラウザが要素を表示しようとして、ウェブページが飛ぶようになります。
 IE9 と IE10 はこのバグがなおされたようです。
2 IE の haslayout 関係
 古いバージョンの IE は悪魔です。。。 具体的に下記をご参照:

3 Firefox と Chrome で要素の default padding などの設定が違う。
 そうすると、div や、button のデフォルト大きさが違います。

4 ブロック要素と インライン要素
 div, p などはブロック要素で、span などはインライン要素です。ブロック要素の中にはブロック要素を含むと、ブラウザが内包したブロック要素の前に終了タグを挿入します。そうすると、たまに、一つ段落の中にスペースができたりします。
 このブロック要素中のブロック要素をインライン要素に変更したら、自動的に変なスペースがなくなります。

5 IE, Firefox 4〜, opera では button type=image の値が submit されない。
 イメージボタンは便利なものですが、その中の value が submit されないので、label + image タグを使った方がいいです。
 これは W3C 標準の解読が違うため、イメージボタンはクリックされた位置だけ送信されるようになっています。
 元々、Firefox 3 は送信しましたけど、 4 からは他のブラウザと同じように送信されなくなりました。
 Chrome は大丈夫です。:)

6 IE で要素が Float 位置が間違う問題
 これは大体 IE7, IE8 で発生します。float を display: inline-block; zoom: 1; に直せば、問題が解消されます。
 続いて、IE の CSS  Hacks:
 
  1. body {  
  2.  colorred/* all browsers, of course */  
  3.  color : green\9; /* IE8 and below */  
  4.  *color : yellow/* IE7 and below */  
  5.  _color : orange; /* IE6 */  
  6. }  
なんかあったら、よく CSS, HTML が良くないから IE での表示が崩れると言われますが、違いますね。 IE 7 は。。。 IE6 はもっとひどいです。
 HTMLタグだったら:
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie ie6 lte9 lte8 lte7"><![endif]-->
<!--[if IE 7]>  <html class="no-js ie ie7 lte9 lte8 lte7"><![endif]-->
<!--[if IE 8]>  <html class="no-js ie ie8 lte9 lte8"><![endif]-->
<!--[if IE 9]>  <html class="no-js ie ie9 lte9"><![endif]-->
<!--[if gt IE 9]><html class="no-js ie gtie9"><![endif]-->
<!--[if !IE]><!--> <html class="no-js not-ie"> <!--<![endif]-->

これも
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
ついでに、一つ JavaScript のエラー:
IE7 では文字列は slice 関数が持ってないから、エラーになります。 IE8〜, Chrome などはちゃんどあります。

cross browser は本来一つ一つのブラウザをみて、少しずつ調整することです。

あ、後一つ
IE 7 から quirks モードの設定はメニューに追加されて、イントラネットのウェブページだったら、自動的に quirks モードになります。
そうすると、Layout が大体崩れます。そのチェックを外した方がいいです。
ふろしき.js


2013年12月8日日曜日

JSON の面白い歴史 - Stay Simple, Stay Stable

こんにちは。 昨日いろいろ読んでいた間、偶然このビデオを発見しました。
面白いです。
Douglas Crockford: The JSON Saga

結構前から JSON を使っていましたが、json.org も何度も読んでました。
ただ、このサイトは Douglas Crockford 作ったことは知りませんでした。
Doug は JavaScript: the good parts の作者であり、YUI, JSLint の開発者でもあります。
自分はかなり前からJSLint, YUI も使っていましたし、JavaScript: the good parts も何度も読んでました。
彼は JS の神様だと思っています。(笑)

ビデオの主な内容:
・どう JSON を発見したか
 →  JSON format のアイディアは前からあったので、発明ではなくて、発見。  開発中に、 JSON は使いやすいことを気づいた。 → Doug は謙遜ですね。 :)

・何で JSON を使ったか
 → Data Format として、JSON は Web に適している。

・何で XML を使わないか
 → XML はドキュメントのフォーマットですから、データのフォーマットではない。

・JSON はバージョンがないから、一度だけ改訂があって:コメントを除去、 e にナンバーに追加。
 → それで、未来でも同じように使える → 今後改訂の予定もないそうです。
 → もし、JSON は足りないと思ったら、他のフォーマットを使ってください。

・JSON のライセンス 
 → The software shall be used for Good, not Evil.
 → Doug は MIT ライセンス好きだそうです。
 → このコードは使いたいなら、使ってください。ただ何かあったら、私を告訴しないでください。
 → Doug も IBM とのエピソドを披露しました。多分上の一言では、IBM が安心できないと思っただろう。それで、Doug は下記のメールを IBM に送った:
 I give permission to IBM, its customers, partners, and minions, to use JSLint for evil.
 - 私は IBM, およびそのお客さん、パートナー、ミニョンに 罪悪のために、JSLint を使う許可を与えます。
 → IBM からは Thanks very much, Douglas! との返事がありました。→最近一番の笑い事。:D

・JSON のロゴについて
 → 最初はそれほど考えてないけど、今見えると、いろいろ面白いとおっしゃってました。

前から XML でデータをサーバーからもらうことを考えると、 JSON のほうが百倍使いやすいし、速いです。
2005年ぐらい JSON は人気になって、IT 業界ではいいアイディアがいつかなからず発見され、流行ると。:)

タイトルにあった Stay simple, stay stable はこのビデオを見たあとの感想です。

それでは。