続・HTML5のCustom Data Attributeをもう少し調べながら、HTMLドリヴンな実装を試みる

気になってきたので、実装したり調べたり

みなさん、仕様に適合した状態でmixiチェックボタンを実装するには実は元のHTMLがHTML5である必要があるんですよ!Tue Oct 26 13:59:14 via Echofon

タイムラインを見てたら、RTで流れてきた発言が目にとまったので、mixiチェックの仕様も確認してみた。

技術仕様 << mixi Developer Center (ミクシィ デベロッパーセンター)

なるほど、a要素に対する必須属性として、data-keyが指定されているので、HTML5として宣言しておく必要があるようだ。とはいえ、世間的にはHTML5の流れに乗るには、<!DOCTYPE html>って言うだけでいいんだよ!って標榜してる風潮なので、そのノリで言えば、面白がることはあっても、それ以上突っ込むほどの仕様では無いかな?

ここでもやはり気になるのは、data-keyだとかdata-urlだとか平凡な名前を指定していること。何かしらの仕様同士が衝突して困るようなことは無いのだろうか。data-urlぐらいはページのパーマリンクが入るであろうことを考えれば、あまり問題でないけれども、data-keyのようなどこの所属のキーが入るか分からない抽象的な属性はちょっと危ないんじゃ。

そんな周辺事情を気にしつつ、Custom Data Attributeの(草稿段階の)仕様に乗っかって、少し書いてみようということでレッツトライ。

Custom Data Attributeを使ってHTMLドリヴンを目指したJSONのリスト取得

パラメーターが多すぎて、普通にスクリプト書いたほうが...というのはさておき、Custom Data Attributeに倣って、HTMLから駆動させJSON取得〜リスト表示するスクリプトを書いてみました。

※HTMLの既存属性で無理矢理バリデートも通過してやろう的な同機能の実装が、手元にあったので改造してみました。

HTML

<ul class="ah-get_jsonp"
    data-ah-url     = "http://search.twitter.com/search.json?q=ablogcms&amp;rpp=7";
    data-ah-method  = "get"
    data-ah-needle  = "results"
    data-ah-callback= "callback"
    data-ah-tmplid  = "ah-tmpl_twitter"
    style="display:none;"
>
    <!-- .ah-get_jsonp-tmpl -->
</ul>
<script id="ah-tmpl_twitter" type="text/xml">
    <li><img src="{profile_image_url}" alt="{id}" width="16" height="16"  /> @<a href="http://twitter.com/{from_user}" target="_blank">{from_user}</a>: {text}</li>
</script>

従来のマークアップからすると、見慣れない感じのHTMLにはなってしまっていますが、割と納得できる感じのマークアップです。HTML5でマークアップしてある自分のブログに載せる分には、どうせValidなので問題もなし。

JavaScript ( jQuery )

$('.ah-get_jsonp').each(function()
{
    var $self   = $(this);
/*
    // datasetプロパティは、Safari5, Firefox3.6では未実装(と思われる)
    var url     = this.dataset.ahJsonp;
    var method  = this.dataset.ahMethod;
    var needle  = this.dataset.ahNeedle;
    var callback= this.dataset.ahCallback;
    var tmplId  = this.dataset.ahTmpl;
*/
    var url     = this.getAttribute('data-ah-url');
    var method  = this.getAttribute('data-ah-method');
    var needle  = this.getAttribute('data-ah-needle');
    var callback= this.getAttribute('data-ah-callback');
    var tmplId  = this.getAttribute('data-ah-tmplid');

    var tmpl    = decodeURI($('#'+tmplId).text());

    $self.empty();
    $.ajax({
        type    : method.toUpperCase(),
        url     : url,
        dataType: 'jsonp',
        jsonp   : callback,
        success : function(json)
        {
            if ( needle == '' ) {
                var all = json;
            } else {
                var all = json[needle];
            }
            var iz  = all.length;

            for( var i=0; i < iz; i++ ) {
                var row = all[i];
                var tmp = tmpl;
                for ( var k in row ) {
                    if ( typeof(row[k]) == 'object' ) { continue; }
                    tmp = tmp.replace(new RegExp('{'+k+'}', 'g'), row[k]);
                }
                $self.append(tmp);
            }
            $self.show();
        }
    });
});

実装してみて思いましたが、なにかしら一意なCustom Data Attributeや、class名をトリガーにしてJSを駆動させる分には、data-urlやらdata-descだろうと、そこまで問題にはならなそうな印象。それでも開発上の柔軟性を保つことを考えたら、やっぱり衝突の危険性についても、命名時からして考慮しておくべきだとは思います。

あと、草稿に従ってdatasetプロパティを指定してみたけれど、さすがに早すぎたみたい。FirefoxもSafariも、現時点では対応していないみたいでした。

Unfortunately, the new dataset property has not yet been implemented in any browser, so in the meantime it’s best to use getAttribute and setAttribute as demonstrated earlier.
HTML5 Custom Data Attributes (data-*) | HTML5 Doctor

試したい・デモしたいなら、getAttributeとsetAttributeが鉄板だよ、って。

Custom Data Attribute適用前の無理矢理HTMLドリヴン

JS側の処理は、前項と大差ありませんが、form要素の属性たちが、かなりこじつけた感の溢れる指定になっています。

※属性で解決しようとしたから不細工なのであって、microformats的にclassやrelを埋め込みまくって定義したほうが美しいんじゃないか、というのはモチロンの所。

<form class="js-jsonp2tpl" method="get" target="results" title="callback" style="display:none;" action="http://search.twitter.com/search.json?q=ablogcms&amp;rpp=7">;
    <ul class="js-jsonp2tpl-wrap">
        <!-- .js-jsonp2tpl-loop -->
    </ul>
    <script class="js-jsonp2tpl-loop" type="text/xml">
        <li><img src="{profile_image_url}" alt="{id}" width="16" height="16" /> @<a href="http://twitter.com/{from_user}" target="_blank">{from_user}</a>: {text}</li>
    </script>
</form>

わざわざscript要素の中にテンプレートが書いてあるのは、src="{profile_image_url}"のような404まっしぐらなリソースへのアクセスを抑制するためです。もしもテンプレートをulの中に書くと、対処しない限りページがロードされた時点で404まっしぐら。

マークアップの専門家の意見が尊重されるべき時代がくるかも?

今のところ、JavaScriptでUIをつくるタイプのWebアプリケーションの実装は、ほとんどフロントエンジニアないし、オールレンジなエンジニアの独壇場な気がしています。

しかし、この先HTML5のようなWebアプリケーションを意識した仕様が、本格的に尊重されるようになれば、実装時点でHTMLにどの程度無茶をさせてもよいのか、HTMLにどれほど気を遣わなくてはならないのか、ますます重要になると感じます。

もちろんエンジニアがオールカバーするのも有りですが、microformatsだとかWAI-ARIAだとか、microdataだとか、そしてこのCustom Data Attributeだとか、カバーすべき仕様が広範に渡ってくるようだと、マークアップの専門家という立場がご意見番として、より必要とされてもおかしくは無いのかなー、と思いました。