読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

今日のはまり道

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.