dポイントプレゼントキャンペーン実施中!

jQuery UIのドラッグ可能なDialogオブジェクトを複数出し、それぞれが重なる位置へのドラッグを制限したいのですが、やり方がわかりません。
ドラッグ時に呼ばれるコールバック関数で重なりチェックし、位置を書き換えできないかと思っています。
どのようにすればよいでしょうか?

A 回答 (2件)

var Obj = {


 startPositionList: [], // ドラッグ開始位置オブジェクト保持配列
 overlapJudgment: function(dragElement) {
  var dragX = dragElement.offsetLeft;
  var dragY = dragElement.offsetTop;
  var dragWidth = dragElement.offsetWidth;
  var dragHeight = dragElement.offsetHeight;
  var dialogElementList = $('.ui-dialog'); // dialog要素リスト
  // dialog要素リスト走査
  for (var i = 0, l = dialogElementList.length; i < l; i++) {
   var targetElement = dialogElementList[i];
   if (targetElement === dragElement) continue; // ドラッグ要素は対象外
   var left = targetElement.offsetLeft;
   var top = targetElement.offsetTop;
   var areaX = { min: left - dragWidth, max: left + targetElement.offsetWidth };
   var areaY = { min: top - dragHeight, max: top + targetElement.offsetHeight };
   // 重なり判定
   if (dragX > areaX.min && areaX.max > dragX && dragY > areaY.min && areaY.max > dragY) {
    return true;
   }
  }
  return false;
 },
 makeStopCallback: function(n) {
  return function() {
   var elem = this.parentNode; // ドラッグ要素
   if (Obj.overlapJudgment(elem)) { // 重なり判定
    var startPosition = Obj.startPositionList[n];
    // ドラッグ開始位置へ戻す
    elem.style.left = startPosition.left + 'px';
    elem.style.top = startPosition.top + 'px';
    //$(elem).animate({ left: startPosition.left + 'px', top: startPosition.top + 'px' });
   }
  };
 },
 makeStartCallback: function(n) {
  return function() {
   var elem = this.parentNode; // ドラッグ要素
   Obj.startPositionList[n] = { left: elem.offsetLeft, top: elem.offsetTop }; // ドラッグ開始位置オブジェクト保持
  };
 }
};

$(function() {
 $( "#dialog0" ).dialog({
  dragStart: Obj.makeStartCallback(0),
  dragStop: Obj.makeStopCallback(0)
 });

 $( "#dialog1" ).dialog({
  dragStart: Obj.makeStartCallback(1),
  dragStop: Obj.makeStopCallback(1)
 });

 $( "#dialog2" ).dialog({
  dragStart: Obj.makeStartCallback(2),
  dragStop: Obj.makeStopCallback(2)
 });
});

動くコード(良し悪しは置いといて)を読んでみるのが早いと思います。
簡単なコメントしか付けてませんけど、読んでみましょう。

この回答への補足

このままコピーペーストして実行しましたが、意図したように動かないようです。
しかし、プログラムの理論は理解できましたが、私の質問で示したものと違っています。

私はドラッグ終了時に判定したいのではなく、ドラッグ中に判定したいのです。
ただし、ドラッグ中に頂いた例のような動作をさせてもダイアログがちらつくだけです。

補足日時:2010/12/05 00:04
    • good
    • 0

>>No.1補足


質問に「ドラッグ時に呼ばれる」って書いてたね。ごめん。
ただ、重なりのチェックと位置情報は揃ってますから、ある程度理解できたのなら
あとは試行錯誤してもらいたいところですけど。

makeStopCallback, makeStartCallback関数の書き換えと
dragStopFlag, dragCallback関数の追加

   makeStopCallback: function(n) {
    return function(event, ui) {
     var elem = this.parentNode;
     if (Obj.overlapJudgment(elem)) {
      if (Obj.dragStopFlag === null) return; // 何もしない
      var startPosition = Obj.startPositionList[n];
      // ui.position.left, topで現在位置を取得できます
      // ドラッグ開始位置へ戻す
      elem.style.left = startPosition.left + 'px';
      elem.style.top = startPosition.top + 'px';
      //$(elem).animate({ left: startPosition.left + 'px', top: startPosition.top + 'px' });
     }
    };
   },
   makeStartCallback: function(n) {
    return function() {
     Obj.dragStopFlag = false;
     var elem = this.parentNode;
     if (Obj.overlapJudgment(elem)) {
      Obj.dragStopFlag = null; // ドラッグ開始位置で重なっていればnull代入
     }
     Obj.startPositionList[n] = { left: elem.offsetLeft, top: elem.offsetTop }; // ドラッグ開始位置オブジェクト保持
    };
   },
   dragStopFlag: false, // ドラッグ中止フラグ
   dragCallback: function() {
    var elem = this.parentNode;
    if (Obj.overlapJudgment(elem)) {
     if (Obj.dragStopFlag === false) Obj.dragStopFlag = true; // ドラッグ中止
    } else if (Obj.dragStopFlag === null) Obj.dragStopFlag = false; // ドラッグ開始位置で重なっていれば範囲外でfalse代入
   }
-----
 $( "#dialog0" ).dialog({
  dragStart: Obj.makeStartCallback(0),
  dragStop: Obj.makeStopCallback(0),
  drag: Obj.dragCallback
 });
-----
jQuery UI Draggable 1.8.5の書き換え
160行目あたり

 //Call plugins and callbacks and use the resulting position if something is returned
 // Obj.dragStopFlagを利用した終了処理
 var flag = typeof Obj === 'object' ? Obj.dragStopFlag : false;
 if (!noPropagation || flag) {
  var ui = this._uiHash();
  if(this._trigger('drag', event, ui) === false || flag) {
   // このブロックに入ればドラッグ終了
   this._mouseUp({});
   return false;
  }
  this.position = ui.position;
 }

ドラッグを中止させるメソッドへの参照法が分からないのでフラグ使って無理やり終了処理へ入れてます。
不細工だし参考程度に
    • good
    • 0
この回答へのお礼

使い物になりませんが、ま、いいでしょう

お礼日時:2010/12/05 21:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!