JSFiddle - React, Tailwind, and code Playground

by sii_side

HTML

<dl>
  <dd class="dragdrop" style="top:5px; left:120px;">11</dd>
  <dd class="dragdrop" style="top:5px; left:240px;">12</dd>
  <dd class="dragdrop" style="top:5px; left:360px;">13</dd>
  <dd class="dragdrop" style="top:5px; left:480px;">14</dd>
  <dd class="dragdrop" style="top:5px; left:600px;">15</dd>
  <dd class="dragdrop" style="top:65px; left:200px;">21</dd>
  <dd class="dragdrop" style="top:65px; left:300px;">22</dd>
  <dd class="dragdrop" style="top:65px; left:400px;">23</dd>
  <dd class="dragdrop" style="top:65px; left:500px;">24</dd>
  <dd class="dragdrop" style="top:65px; left:600px;">25</dd>
</dl>

CSS

#jquery-ui-draggable {
  width: 100px;
  height: 100px;
  padding: 30px;
  margin: 0;
  border-radius: 10px;
}

dd {
  position: absolute;
  width: 100px;
  height: 50px;
  margin: 0;
  border-radius: 2px;
  border: 1px solid #000;
}

JavaScript

$(".dragdrop").draggable({
  axis: 'x',
  drag: function(e, ui) {
    var _this = this;
    //後で$.eachを使うのでdrag要素のthisを退避しておく
    
    var pLeft = $(this).data("prevLeft") || ui.originalPosition.left;
    //1つ前のdragイベント処理後の位置
    //初回のdragイベント時はui.originalPositionを利用
    //(公式のAPIに説明が無いが、console.dir(ui);したら出てきたので)

		var dif = ui.position.left - pLeft;
    //欲しい数字はこれ!「1回のdragイベントによってどれだけ移動したのか」
		//(originalPositionはdragstopするまで更新されないようなので、2回目以降は使わない)

		//グルーピングの条件がよくわからないので、ここではとりあえず「topが同じもの」とした
    $(this).nextAll().filter(function() {
      if (_this.style.top === this.style.top) {
        return true;
      }
    }).each(function() {
      $(this).css("left", "+=" + dif + "px");
      //1回のdragイベントで動いた分をそれぞれ加算
    });

    $(this).data("prevLeft", ui.position.left);
    //dragイベントはdragstopまでに何回も発生し得るため、移動後の位置を記憶しておく
  },
  stop: function() {
  	$(this).removeData("prevLeft");
    //dragが終わったら削除
  }
});