• ベストアンサー

jQuery UIでドラッグ制限

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

質問者が選んだベストアンサー

  • ベストアンサー
  • my--
  • ベストアンサー率89% (91/102)
回答No.2

>>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;  } ドラッグを中止させるメソッドへの参照法が分からないのでフラグ使って無理やり終了処理へ入れてます。 不細工だし参考程度に

sainte
質問者

お礼

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

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • my--
  • ベストアンサー率89% (91/102)
回答No.1

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

sainte
質問者

補足

このままコピーペーストして実行しましたが、意図したように動かないようです。 しかし、プログラムの理論は理解できましたが、私の質問で示したものと違っています。 私はドラッグ終了時に判定したいのではなく、ドラッグ中に判定したいのです。 ただし、ドラッグ中に頂いた例のような動作をさせてもダイアログがちらつくだけです。

すると、全ての回答が全文表示されます。

関連するQ&A