今日のはまり道
Yahoo! UI Library のTreeViewで以下の条件を満たす場合、クリックイベントの引数で渡されてくるeventの「ctrlKey」プロパティが参照できなくなります。
- クリックイベントとダブルクリックイベントの両方にリスナが登録されている。
- ブラウザがIE
IE7+Yahoo! UI Library 2.7.0 で確認。再現サンプルは以下です。
var out = document.getElementById( "out" ); var tree = new YAHOO.widget.TreeView("tree"); new YAHOO.widget.TextNode("node1", tree.getRoot(), false); new YAHOO.widget.TextNode("node2", tree.getRoot(), false); new YAHOO.widget.TextNode("node3", tree.getRoot(), false); tree.draw(); /*イベントを割り当て*/ tree.subscribe( "clickEvent", function( ev ) { // IEでクリックイベントとダブルクリックイベントの両方を割り当てると、 // event.ctrlKeyが参照できなくなりエラーになる。 out.innerHTML += "click : " + ev.event.ctrlKey + "<br/>" }); tree.subscribe( "dblClickEvent", function( ev ) { out.innerHTML += "dbclick : " + ev.event.ctrlKey + "<br/>" });
登録をクリックイベントだけにすると、正しく動作します。
var out = document.getElementById( "out" ); var tree = new YAHOO.widget.TreeView("tree"); new YAHOO.widget.TextNode("node1", tree.getRoot(), false); new YAHOO.widget.TextNode("node2", tree.getRoot(), false); new YAHOO.widget.TextNode("node3", tree.getRoot(), false); tree.draw(); /*イベントを割り当て*/ tree.subscribe( "clickEvent", function( ev ) { out.innerHTML += "click : " + ev.event.ctrlKey + "<br/>" });
原因
ダブルクリックイベントが登録されている場合、クリックとダブルクリックを判定するためタイマーで一定期間待ってからイベントを発火するコードになっており、ここで待機中に「window.event」が書き換えられてしまうのが原因。
対策
タイマーを起動する前にイベントオブジェクトをコピーしておくことで回避できます。具体的には、treeview.jsの649行目あたりに以下を追加すればとりあえずOK。
// IEでctrlKeyが参照できない問題の対策 var tmp = {}; for ( var i in ev ) tmp[i] = ev[i]; ev = tmp;
本日はこれで3時間くらい浪費。orz.