トップ «前日 最新 翌日» 編集
RSS feed

ただのにっき


2010-03-24(水) [長年日記]

Webkitではイベント系の属性をJavaScriptから書き換えられない(の?)

最近まじめにAjaxプログラミングを始めてですね(今ごろかいな)、jQueryで楽ができる時代から始めるとハードル低くていいっすよ、ホント。

[スクリーンショット]paymemoの画面 で、だいぶ前から自分の浪費っぷりを可視化しないといかんなーと思っていたので、それを題材に「単に使ったお金を記録するだけのWebアプリ」を作ってみている。GETでデータを取ってきて、POSTでデータを投げるのでいい題材。これをiPhone用のビジュアルにすれば、日常的に使えるだろう。たぶん自分にしか実用性がないけど、ソースはgithubにて(→paymemo)。サーバサイドでいまだに「require 'cgi'」とかしてるのをなんとかしろって感じだが。もちろんドキュメントはない。

Firefox上での開発はまったくスムーズでたいした困難もなかったのだが、これを肝心のiPhone上で実行すると追加ができない。Ajax使ってるはずなのに画面遷移が起きちゃう。試しにChromeでやってみたら同じ現象なので、Webkitだけの問題らしい。

いろいろ(中略)調べてみたところ、Submitボタンにあとから「onclick」を追加していたためだとわかった。WebkitだとこれがDOM上に反映されない。onclickを食ってなければ画面遷移が起きるのは当たり前やねぇ。ChromeにもFirebugが提供されてて助かった。他にも、formにonsubmit属性を追加しようとしてもダメだったので、Webkitではイベント系の属性は操作できないのかな。

こういう非互換情報がうまく見つけられないのは、たぶんもう、誰もonclickとか使ってないからかも知れない。当然、回避策はbindを使ってイベントハンドラを登録する方法なわけで、jQueryではこっちが主流なんだろう。なお、わざわざイベントハンドラを動的追加しているのは同じページ内に複数のお財布を置きたいからなので、「初めからonclickをハードコーディングしておけば?」というのはナシ(やればできるのはわかってるけど)。

で、さっそく使い始めてはや数日。想定どおり自分の浪費っぷりが目に見えて、かなりビビっているのであった。いやー、これは良くないな。ひどいものを作ってしまった。

Tags: ajax iphone
本日のツッコミ(全4件) [ツッコミを入れる]
os0x (2010-03-25(木) 01:18)

jQueryのattrは内部的には色々やってますが、
.attr('onclick','return addNewItem("'+db+'");');
このケースでは単に
element.onclick = 'return addNewItem("'+db+'");';
という処理になります。onclickに文字列を設定してしまっています。

element.onclick = function(){return addNewItem(db);};
もしくは、
element.setAttribute('onclick','return addNewItem("'+db+'");');
といった処理であったら意図どおりに動くだろうと思います。

ちなみに、onclickに文字列を代入したときの動作は、FirefoxとOperaでイベント発生、IEとSafariにChromeはイベント発生せずと結果が分かれました。

ただただし (2010-03-25(木) 12:28)

うわ、わざわざコードまで追っていただいてありがとうございます!

イベントを文字列として設定すると再解釈してくれない実装がある、というのは理解しました。attrならどんな属性も共通に扱えるわけではないんですね。

ただ、文字列として設定したとしても、(Firebugでは)DOM上に見えないのがよくわからないんですけどね……うーむ。

os0x (2010-03-25(木) 15:02)

element.onclick =
element.setAttribute('onclick',
の違いです。前者はJavaScript上のオブジェクトにプロパティをセットしているだけですが、後者はDOMに属性を追加しています。
後者はFirebugのHTMLパネルにも反映されますし、親要素からinnerHTMLを見たときにonclickが存在しています(なのでinnerHTMLで書き変えてもイベントが残ります)。IEとか、ブラウザによってはまた事情が違ったりしますが…。

ただただし (2010-03-25(木) 17:44)

いろいろ試してみて理解しました(まだ「なんとなく」ですけど)。

DOMに反映されるからといって優先されるわけでもなく、どちらかというとプロパティの設定が実行対象になる実装が標準的みたいですね。Firebug上で見えるものと実行されるものが食い違うというのはなんとも気持ち悪いですけど、そういうものだと割り切るしかないんだなぁ。

それにしても、こんな単純なサンプルで、しかもjQueryを使っていながらブラウザ間非互換に当たるなんてもう! >_<;


トップ «前日 最新 翌日» 編集
RSS feed