2009年8月26日水曜日

jQueryUIのSelectableにバグ?

jQueryのUIプラグインにふくまれるSelectableプラグインにはどうもバグのようなものがある。

(jQuery 1.3.2、jQuery UI 1.7.2、Firefox 3.5)

■親子(孫)関係にある要素で「選択」動作が混乱

要素A、B、C、D、E、…という順番で入れ子構造になっているHTMLの要素(たとえばDIV要素)があって、

  1. 要素Dのselectableメソッドを呼び出して、要素E(たち)を選択できるようにする( D . selectable ( [ {Object} options ] ) )。
  2. 要素Dのselectableメソッドを、文字列"destroy"を引数にして呼び出して、Eの選択可能状態を解消する(D . selectable ( "destroy" ))。
  3. 次に要素Bに対して、selectableメソッドを呼び出して、要素C(たち)を選択可能にする。
  4. 要素Bのselectableメソッドを、文字列"destroy"を引数にして呼び出して、Cの選択可能状態を解消する。
  5. もう一度、要素Dのselectableメソッドを呼び出して、要素E(たち)を選択できるようにする。

このようにした状態で、要素Eをクリックしても、「選択」(select)イベントは起きない。そしてなぜか、selectingイベント中、要素Cが「選択」イベントの対象となる。

これは例えばselectingイベントリスナの第2引数であるuiオブジェクトのselectingプロパティを参照するとこれがわかる。

またFirebug等でDOMとしての要素Cを監視していると、要素Eがクリックされたとき、(要素Eではなく要素Cに)"ui-selecting"クラスが付加され、マウスクリックが終わってもそのまま残されることがわかる(本来はselectingイベントが終了したのだから自動的に"ui-selecting"は取り除かれなくてはいけない。この不完全な動作が、Selectableプラグイン内部で問題の起きている証拠?)。

「選択」動作が終了すると、selectstopイベントは起きる。けれども、要素Eに(その要素が「選択」されたことを示す)"ui-selected"クラスが付加されることはない。

どういう理由か分からないが、Selectableプラグインの内部では、「5」の段階でも、選択可能な要素の一覧として、要素C(たち)の情報が何らかのかたちで残存してしまっているらしい。

■この問題を回避する方法

「回避する方法」といってもかなり奥の手的なのだが…、手順「4」のあと、Aのhtmlメソッドを呼び出して、Aの内側のHTML要素を文字列のかたちで取り出し、それをそのままAのhtmlメソッドに渡す( A . html( A . html() ) )。そして手順「5」を実施する。

こうすると、BやCやDやE(のどこか)に要素(DOM)に結びつけられている「選択」可能な要素の情報が破棄されて、うまくいく。…みたい。

0 件のコメント: