Ajax 最適化 Tips : 要素をカスタマイズする理想的な方法
HTML 内で要素をカスタマイズするための書き方はろいろありますが、おそらく理想的な方法は以下のようになるでしょう。
foo.js:
function init(element) { $(element).observe('click', function() { alert('Clicked!') }); }
foo.jsp:
<div onelementready="init(this)"> Custom Element </div>
しかし onelementready などというイベントは存在しないので、
foo.jsp:
<div id="element1"> Custom Element </div> <script type="text/javascript"> init($('element1')); </script>
とやったり、
foo.jsp:
<div id="element1"> Custom Element </div> <script type="text/javascript"> init(document.scripts[document.scripts.length - 1].previousSibling); </script>
とやったり、
foo.jsp:
<div id="element1" onmouseenter="init(this)"> <!-- 遅延させる --> Custom Element </div>
とやったりしますが、それぞれ一長一短があり、どれかを一般的な手法として用いることはできません。
そこで上記の理想を実現してみました ( 実用できるレベルではありません )。ソースコードは
http://code.google.com/p/elementevent/
から取得できます。
IE の Behavior と Firefox の XBL という機能を使って無理矢理実現しています。言うまでもありませんが、 Opera や Safari では動きません。
これを使えば、要素生成時と要素破棄時のイベントをハンドリングすることができるようになります ( 正確にはスタイルがアタッチされたときとデタッチされたとき ) 。 要素生成時は onelementready で、要素破棄時には onelementdispose でハンドリングします。なお、パフォーマンスの劣化を防ぐために elementevent クラスがある要素のみ利用可能になっています。
<div class="elementevent" onelementready="alert('Element is ready.')" onelementdispose="alert('Element is disposed.')" />
属性が指定されていれば、どのような要素の生成のされかたでも正しくハンドリングできます。以下のような HTML を書いて、
<html> <head> <link rel="stylesheet" href="elementevent.css" type="text/css" /> <title>elementevent test</title> <script type="text/javascript"> function ok(text) { var test = document.createElement('div'); test.innerHTML = text + ' : <i>ok</i><br />'; document.body.appendChild(test); } </script> </head> <body> <div class="elementevent" onelementready="ok('onelementready on static element')" onelementdipose="ok('onelementdispose on static element')"> <span class="elementevent" onelementready="ok('onelementready on inner static element')" onelementdipose="ok('onelementdispose on inner static element')"> </span> </div> <script text="text/javascript"> var element = document.createElement('div'); element.className = 'elementevent'; element.setAttribute('onelementready', "ok('onelementready on dynamic element')"); element.setAttribute('onelementdispose', "ok('onelementdispose on dynamic element')"); document.body.appendChild(element); var html = '<span class="elementevent" ' + 'onelementready="ok(\'onelementready on element generated by innerHTML\')" ' + 'onelementdispose="ok(\'onelementdispose on element generated by innerHTML\')"></span>'; element.innerHTML = html; </script> </body> </html>
ブラウザで読み込ませると、
onelementready on static element : ok onelementready on inner static element : ok onelementready on dynamic element : ok onelementready on element generated by innerHTML : ok
と表示されます。
注目すべきは従来の方法ではどうしても必要だった script タグが完全に除去されている点です。また、これを用いれば HTML に不必要なロジックを埋め込まざるを得ない状況も回避できるようになります ( ロジックの分離 ) 。実用できるレベルであれば夢のような機能ですが、対応ブラウザが少ないのと、イベントの発火タイミングがかなり曖昧なのとで、なかなか実用できないでいる次第です。
まあ、パフォーマンス上の懸念がなければ従来の方法でも十分だと言えばそうなのですが。
- Category(s)
- ajax
- performance tuning
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/custom-element-initialization/tbping
Re:Ajax 最適化 Tips : 要素をカスタマイズする理想的な方法
DOM の仕様には mutation event というのがあるので、
それに名前を揃えておくとおしゃれかも知れません。
http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MutationEvent
衝突を避けるために違う名前にしておくのも、
それはそれでアリだとは思います。