IE での Draggable の話の続き

つまりこういうのがあれば良いんじゃないかと思うわけです。

//------------------------------------------------------------
// 条件によってドラッグを中断するための仕組み(IE対策)
//
Object.extend(Draggables, {
  include: function(draggable)
  {
    return this.drags.include(draggable);
  }
});

Object.extend(Draggable.prototype, {
  exclude: function(elements)
  {
    if (!Object.isArray(elements))
      elements = [elements];

    var end_drag = function() {
      if (Draggables.include(this))
        this.destroy();
    }.bindAsEventListener(this);

    var start_drag = function() {
      if (!Draggables.include(this)) {
        Event.observe(this.handle, "mousedown", this.eventMouseDown);
        Draggables.register(this);
      }
    }.bindAsEventListener(this);

    for (var i = 0; i < elements.length; i++) {
      Event.observe($(elements[i]), "mousemove", end_drag);
      Event.observe($(elements[i]), "mouseout",  start_drag);
    }
  }
});

例えばこういう HTML があって、

<div id="listwindow">
  <div id="metavarlist" style="overflow: scroll;">
    メタ変数リストだよ
    <ul>
      <li>foo</li>
      <li>bar</li>
      <li>hoge</li>
      <li>fuga</li>
      ....以下いっぱい...
    </ul>
  </div>
<div>
var window = new Draggable("listwindow");

みたいにすると、listwindowがドラッグ可能になります。それはそれで良いんだけど、リストが大きくなってスクロールバーが出たときに、そいつをスクロールをしようとすると、ウインドウが一緒についてきてしまってスクロールどころの騒ぎじゃなくなります。

そこで、

window.exclude("metavarlist");

としてあげると、metavarlist の中でのドラッグが(Draggable的な意味で)無視されて、目出度くスクロールができるようになりました。

ほんとはコンストラクタ引数で渡せるようにすると良いと思うけど、本体を弄るのは気がひけるのでやりませんでした。本体を弄るとバージョンアップに追従するのが面倒になるし、もっと良い方法が実はあるのかもしれないし。でもこれしか方法がないなら、最初からこの機能を持つべきだと思います。