HOKYPOKY.BLOG

Facebookのフロントエンド技術

Hello Facebook!!

Facebookはじめました。

「Facebookが流行っている理由がわからない」「Facebookは流行るのか!?」などなど言われてるけど、結局はSNSは流行りものであり、mixiが何故面白かったのか、Twitterが何故面白いのかというのも「人がいるから」という理由に他ならないと思っています。
実は、こっそりTwitterのアカウントを別で作ってみたりしたのだけど、誰もフォローしていない、誰にもフォローされていないとそりゃーもうつまらないつまらない。つまり「人がいれば面白い、人がいなければつまらない」。それだけのことです。
流行るか流行らないかはディティールこそ異なれ「話題になったかどうか」なので映画とか大事ね。

で、最近Facebookで友達を積極的にフォローしてそこそこに楽しくなってきました。
色々いじってみて分かったのが「Facebookの技術力がすごい」ということです。

バックエンドでは色々と話題にもなっていますが、フロントエンドもすごかった。
いくつか気がついた点をピックアップしてみます。

バックエンドについて色々は以下などが参考になるかと。
PHPをC++に変換して高速化する「HipHop for PHP」をFacebookが公開
タグ “Facebook” の記事一覧 - Publickey

FBML

FBML(FacebookMarkupLanguage)
http://developers.facebook.com/docs/reference/fbml/

要はFacebookのHTML API(実際はXMLとJavaScriptの実装)。
ファンページやアプリではこれを使ってサイトを作らないといけないのだけど、これはFacebook外のページでも使うこともできます。

例えば、こんなページを作ることができます。
http://www.hsiet.com/winery/storybar.html
さすがにこれは「デザインしょっぺぇ!!」って突っ込みたくなりますね。
ただ、実際にソースをみるとというタグがいっぱいある。

Facebook連携をクライアントサイドだけでできてしまうのは、とても便利。
以下をhead内に入れてあげればFBMLをサイトで使うことができます。

<script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script>

手始めに、このブログでもFBMLを使いウィジェットを設置。
あとはファンページも作成。
実際は簡単なアプリも作ってみたのだけど、これはいつか記事にするかも。

※ 余談ですが、ファンページのURLを固定化するには25人以上のファン(「いいね!」)がいないといけないらしい。
ぜひ「HOKYPOKY.info ファンページ」から「いいね!」して下さい!!

HTML5時代のAjax

実はココが一番良いたいこと。
タイトルを「Facebookに学ぶ、HTML5時代のAjax」とかにすればよかったかもしれない。

まずはこの記事をみてください。

TwitterやFacebookのURLには、なぜ#!が含まれるのか (SEOとAjaxのおいしい関係)

要はGoogleが「http://〇〇.com/xxx/#!hoge」となっているページを「http://〇〇.com/xxx/?_escaped_fragment_=hoge」として解釈してクロールするという話。

実際にバックエンドでhttp://〇〇.com/xxx/?_escaped_fragment_=hogeを用意してあげればAjaxを使ってもSEO的にOKなのです。

しかしこの方法は、すこし古いことが判明。

というのも実は、最近のfacebookでは「#!」がつかない。(ブラウザはChromeとSafari)
URLかわってるのにFacebookって爆速だなーと思って調べていたら、HTML5の「History API」を使っていて、実際は全てAjaxだったのでした。

Histroy APIはブラウザの「戻る/進む」をJavaScriptから操作できるもの。

地味っすなー。

だけどコレを使えばAjaxとSEOを両立できるのです。鍵は「history.pushState()」

// using jQuery
(function($){
  $(function(){
    $("a").click(function(){
      // history.pushStateを使うことで擬似的にURLのパス、ブラウザの履歴を変更する
      // ドメインをまたぐことはできないので安全。
      history.pushState({path: this.pathname}, (this.title ? this.title : document.title), this.href);
      $.ajax({
        url: this.href,
        success: function(data){
          // do something
        }
      });
      return false; // これで本来のaタグのリンクの挙動がキャンセルされる。
    });
  })
})(jQuery);

とても簡単にURL変更と履歴を残しつつ「ページを遷移させない」ことができました。
ページが遷移しないのでAjaxなどで情報を更新すればいいわけです。

レガシーブラウザやロボットに対してはAjaxをオフにして、モダンブラウザではAjaxを使って軽量化、高速化、エフェクティブにするなどの実装が望ましいですね。

(((【【【[[[HTML5]]]】】】) ))

バックエンドの実装もビューはスタティックなHTMLとAPIの連携となっていき、負荷軽減やクロスプラットフォーム化が進みますね!

まとめ

紹介したのは恐らくFacebookからすればほんの一部ですが、FacebookやTwitterなど流行りのWebサービスはたしかな技術力というのが付いてきているなーというのを実感しました。また気がついたらこのブログでも紹介していきたいと思います。

映画「ソーシャル・ネットワーク」は来週観に行こうと思います。

下の「いいね!」宜しくです!

jQuery 1.3を試す

jQuery1.3が出てたので少しためしてみた。jQueryはJavaScriptが楽しくなる魔導士みたいな存在です。

http://docs.jquery.com/Release:jQuery_1.3

以上を見てみるとどうやらセレクタ周りがかなり高速化していますね。
sizzleというCSSセレクタエンジンを採用している様子。
セレクタのパースにモダンブラウザの場合ネイティブの関数をなるべく使うようにしたっぽい。

また、liveQuery pluginも内包しています。
これはlive(), die()関数のところかな。 

そして当然と言えば当然なのですが「jQuery foundation」設立。

さらにnew API Browser、しかもAIRアプリになっていたりで、大事になってきてます。

実際の大きな変更点といえば

  • “[@attr=value]“の@を廃止。(まだ大丈夫)
  • “a, b, c” セレクタの廃止。
  • live(), die() 追加

上の二つは、まだ大丈夫なはずなんだけどCSSセレクタエンジンにおいて、これらの記法を考慮すると遅くなるんだとさ。JavaScriptも高速化の時代ですもんね。
たしかに大量のDOMを操作していると重くなったりします。

さっそく試してみる

AIRアプリ

インストールが簡単なのと、WEBに比べて高速なのがうれしい。微妙に重かったんだよね。英語だけどサンプルがしっかりのってるし良くわかる。

あとは、お気に入り機能がうれしいところ。「これ何かに使える」的なものでもいいし、探した結果を一時的に保存するでもいい。

live(), die()

次はlive関数とdie関数を使ってみます。

live関数は先にイベントを定義しておくことができ、動的に発生したDOMにもイベントを付与することができるみたいです。

$("p.myObj").live("click",function(){
    alert($(this).text());
});

これはp.myObjというものができた場合、自分の中にあるテキストをアラートするといったもの。
これで例えばAjaxで読み込んだDOMなんかにも勝手に適用できていいですね。
というか、これはready()のタイミングじゃなくていいのかな。だとしたらかなり色々楽になりそう。

die()はlive()の逆。なんとも恐ろしい名前なんだろう。要はliveで定義したイベントを削除するというもの。
これはあまり使わないかな。スペックアップや、コアなところでしか使わないはず。

とまあlive関数に関しては有効的に使える場面が多く、恩恵は凄まじい。
また、スペックアップなどがやっぱりうれしいので1.2から移行しなくては。とりあえず今つくってるライブラリたちの文法で廃止されるものを書き換えないと。

new function() {} と (function(){})() の違い

まずいきなりですが、JavaScript、全てが関数であり、クラスです。

var str = "hello";

は以下のように書き換えられます。

var str = new String("hello");

そして全ての関数はクラスとなります。
クロージャを使った形だと

var myClass = function () {
    this.hello = function () {
        alert("hello");
    }
}
var instance = new myClass ();
instance.hello(); //hello

prototypeを使った形だと

var myClass = function () {}
myClass.protorype.hello = function () {
    alert("hello");
}
var instance = new myClass();
instance.hello(); //hello

とすることもできます。
このあたりもクロージャとprototypeの違いがあるらしいんですが本題ではないので割愛。
ってかよくわかってない。

もうちょっと寄り道します。

JavaScriptではnewするとインスタンスになります。
つまりJavaScriptは全て関数で、newというのは、インスタンスを作るということ。
classというものはなく、逆にいうと全部クラスなので特にclassと定義することはありません。
“”,(),{}はnew String(),new Array(),new Object()の略。
さらにnewしたものはインスタンスなのでさらにnewすることはできません。
だから

var str = "hello";
var instance = new str();

とはできません。
またnewすると中身が実行されます。
これがコンストラクタとなります。

一方でjavascriptの関数の実行方法は二通りあります。

foo();
(foo)();

二通りある理由がよくわかりませんがとりあえず二通りあります。
寄り道の寄り道をすると()はArrayということだったので以下のような関数を実行してみたんですが、

function func1 () {
    alert("function 1");
}
function func2 () {
    alert("function 2");
}
(func1,func2)();

結果は「function 2」となりました。このあたりが謎。

話を少し戻します。
関数では名前をつけることができます。
また、変数に関数を詰め込むことができます。

関数に名前をつけたパターン。

function myFunc () {
    alert("myFunc");
}

変数に関数を詰め込んだパターン

var myFunc = function () {
    alert("myFunc");
}

この二つの違いは結構簡単で、関数に名前をつけたパターンは、スクリプト実行の最初に定義されます。
つまり以下はエラーになりません。

myFunc();
function myFunc () {
    alert("myFunc");
}

逆に変数に関数を詰め込んだパターンだと以下はエラーになります。
一応先にvarで定義してもエラーになります。

var myFunc;
myFunc();
myFunc = function () {
    alert("myFunc");
}

こうするとうまくいきます。

var myFunc;
myFunc = function () {
    alert("myFunc");
}
myFunc();

じゃあこの変数に詰め込んだ関数とはなんでしょう。
言葉を使い簡単に説明すると無名関数といいます。

名前をもって生まれたものと、生まれたあとで名前をつけられたものの違いですね。
もちろん、無名関数でないものも変数につめることはできます。

var myFunc2 = myFunc;
function myFunc () {
    alert("myFunc");
}

以上をふまえて new function() {} と (function(){})() の違いを説明します。
やっと本題なんですが、この記事だけみると逆に上の二つは明らかに違うのが分かると思うんですが、実は挙動としてはほぼ一緒なんです。
簡単に言うと、「即実行される関数」という感じです。

キーワードになるのが無名関数。

function () {}

これを単純に無名関数じゃなくすると

function someFunction () {}

という風になります。
someFunctionという名前にしました。

それをそれぞれnewや()()で呼び出してみると

new function () {}

つまりこれは

new someFunction();

となり

(function () {})();

こっちは

(someFunction)();

となります。

newはインスタンスとして実行するということ。
()()は関数呼び出しでした。

newの場合は無名関数クラスをnewしていて、そのコンストラクタが実行されています。
だから即実行されていました。
()()の場合は、もともと関数を実行するという意味。

つまりクラスとして使う場合はnew。
関数を即実行する場合は()()を使うということになります。

この二つが実際にどう影響をあたえるかというと、newはインスタンスになるのでthisのフォーカスがインスタンスになります。
対して()()の場合はインスタンスでもなんでもないので、親のthisを継承します。

個人的にはnew function(){}派なのですが、どうやら(function(){})()派も多いみたいです。
でも、ここらへんが分かってればどっちでも大丈夫そうです。

長いメモになってしまった。
去年もこのあたりについて調べたんですがようやく理解できました。  
プログラムって大変。パソコン偉い。

Safariでaltを表示する。

仕事でサイトを作る際に、HTMLの画像にaltを入れるという作業が発生している方は多いんじゃないでしょうか?

altなんてみないっしょ。と、個人的には思うし、さらに一般的にサイトを閲覧しにくる人はaltなんて知らないっしょ。なんて考えたりするのは自由ですがやっぱりきちんとaltの入ったサイトを見ると関心しますし、総合的にクオリティが高いという逆説的な展開もあります。

で、このaltはSafariからだとソースをみないかぎり読むことができないんですね。

例えばFirefoxなんかだとWeb Developerで見ることができるんですが、メインブラウザがSafariなので気軽にチェックしたいときはSafariでみれるととても助かります。

というわけで、実はSafariの場合、「title属性だとIEのaltのようにツールチップがでる」ということを利用したブックマークレットを作成しました。

AltChecker

上のAltCheckerの文字をそのままブックマークツールバーに入れて、見ているページから呼び出すだけでみれます。

オーバーすると、画像に入っているalt、画像名、 画像サイズがツールチップに表示されるのでIEよりも見やすく便利な情報が載っているのではないでしょうか。

他にも、可読性をあげるため、

  • 赤い線で囲われているのが、altナシの画像。
  • 緑の線で囲われているのが、altの先頭または末尾にスペースが入ってしまっている画像。(コピペで入れたりするとたまにこういうスペースが入ってるんですよね。わかります。)
  • 水色の線で囲われているのが空Alt(alt=”")の画像です。(一応表示するもののエラーとはしません。)

といった表示がでるようになり、
また、全てエラーがない場合は”Hi-Ho!”なんていうふざけたalertが表示されますが、これが意外とテンション上がって気持ちがいいもんです。

余談が続きますが、Safariのブックマークバーに登録された「フォルダを除くブックマーク」は左からCmd+1〜9で呼び出すことができます。
こういったブックマークからスクリプトを呼び出すものをブックマークレットと読んだりもするんだけどボクはブックマークレットの名前を「|(縦棒)」1文字にしてます。
他のよく使うブックマークはフォルダにしてます。

こうすることで下図の用にすごく整理されたすっきりとしたブックマークバーの出来上がり!

Safari Bookmark Bar

他の縦棒はTumblrやDeliciousなどのブックマークレット、他の自作ブックマークレットをいれてます。

————————————————– 8<

話は変わりますが、今日の動画はLittle Big PlanetというPS3のソフトなんですが、ブロックとか紐とか仕掛けを組み合わせて自分でステージを作ったりして公開できるとかなんとかで。
そしたらさ、こんなステージ作っちゃう人が世の中にはいるわけ。

つまりね、言ってしまえば、段ボールと、紐と、BB弾で作っちゃったようなものよ。

Flashが3D表示できるようになった。物理演算のライブラリもでてきた。ってときにゲームはここまでぶっとんでるわけで、WEBとゲームの技術というものの差は常に等間隔に開いているのだなと思いました。
というか、WEBはWEBにできることがあって、ゲームとは別物だとそう思う訳です。
しかしこのソフトはいいなー。やりたいなー。

面を作って公開して、オンラインで一緒に遊べるって、実はかなりWEBっぽいってのが実は一番くやしい。

ASDocとJSDoc

最近いろいろ便利なクラスなどと出会い、ソースを覗いてみたりするとコメントアウトの書き方に違和感を覚えた。
というのもコメントアウトが汚いのです。

/**
 * Comment
 * @param someParamators
 */
function function_name (argument) {
    // body...
}

こんな感じ。
しかしこの手のコメントアウトが流行ってるのは確かでこれは何かあるのかもしれないと色々調べていたら○○Docという書式があるらしい。すばらしい!汚いなんていってごめんなさい。

ActionScriptや、JavaScriptによってASDocとかJSDocとか言語ごとにルールがあるのだけど要するにコメントアウトの書式をこれらに準拠して作成すると、コンパイルしてHTMLドキュメントにしてくれるらしい。

伝えづらいのでとりあえずサンプル。
ActionScriptからはTweenerクラス、JavaScriptではShadowBox2.0クラスをそれぞれ文書化してみました。

とくにASDocなんてAdobeのhelpみたいですね。
それもそのはず、ASDocはFlexSDKにふくまれるAdobe謹製。
javascriptはJSDoc Toolkitを使いました。

使い方はそれぞれ以下より。

ASDocはFlexSDKについていて、JSDocはGoogleCodeよりDLしました。

他にもjava, PHP, Rubyなどなど様々な○○Docが作成される模様。
CSSDocなんてものもあるみたい。

最終的に統合された一つの書き方になるといいなと願いつつもやっぱ言語ごとに仕様が違うから難しいのかな。
とりあえずこれらの書式を覚えていきたいと思います。