You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery UI Sortable多连接拖拽时如何根据方向设置state变量

问题描述

使用jQuery UI的Sortable实现两个列表的拖拽排序,需求如下:

  • 将#sortable2中的<li>拖拽至#sortable1时,变量state赋值为0
  • 将#sortable1中的<li>拖拽至#sortable2时,变量state赋值为1

原实现代码如下:

原JavaScript代码

$(function() {
  $("#sortable1, #sortable2").sortable({
    connectWith: ".connectedSortable"
  }).disableSelection();

  $("#sortable2").sortable({
    update: function(event, ui) {
      $(this).children().each(function(index) {
        if ($(this).attr('data-position') != (index + 1)) {
          $(this).attr('data-position', (index + 1)).addClass('updated');
        }
      })
      saveNewPositions();
    }
  }).disableSelection();
});

function saveNewPositions() {
  var positions = [];
  $('.updated').each(function() {
    positions.push([$(this).attr('data-index'), $(this).attr('data-position'), $(this).attr('data-type')]);
    $(this).removeClass('updated');
  })

  $.ajax({
    url: SITE_URL + 'standart/islem.php?page=sortable',
    method: 'POST',
    dataType: 'text',
    data: {
      positions: positions,
      pageID: 1,
    },
    success: function(data) {
      data = data.split(":::", 2);
      var message = data[0],
        answer = data[1];
    }
  })
}

原HTML代码

<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>

<ul id="sortable1" class="connectedSortable">
  <li data-index="1" data-position="1">first row</li>
  <li data-index="2" data-position="2">second row</li>
</ul>
<ul id="sortable2" class="connectedSortable">
  <li data-index="1" data-position="1">2. first row</li>
  <li data-index="2" data-position="2">2. second row</li>
</ul>
解决方案

要实现跨列表拖拽时的state赋值,核心是利用jQuery UI Sortable的**receive事件**——该事件会在元素从另一个关联的Sortable容器被拖拽进来时触发。结合ui.sender可以获取元素的原父容器,从而判断拖拽方向。

另外需要注意:原代码中重复初始化了#sortable2的Sortable,这会导致事件绑定冲突,需要合并为一次初始化,并为两个容器统一绑定必要的事件。

修改后的完整代码

JavaScript代码

$(function() {
  // 初始化两个Sortable容器,统一配置事件
  $("#sortable1, #sortable2").sortable({
    connectWith: ".connectedSortable",
    // 元素从外部拖拽进来时触发
    receive: function(event, ui) {
      let state;
      // 判断原容器和目标容器
      if (ui.sender.attr('id') === 'sortable2' && $(this).attr('id') === 'sortable1') {
        state = 0; // 从sortable2到sortable1
      } else if (ui.sender.attr('id') === 'sortable1' && $(this).attr('id') === 'sortable2') {
        state = 1; // 从sortable1到sortable2
      }
      
      // 这里可以根据state做后续处理,比如传入saveNewPositions
      console.log('当前state值:', state);
    },
    // 排序完成后更新位置信息
    update: function(event, ui) {
      $(this).children().each(function(index) {
        if ($(this).attr('data-position') != (index + 1)) {
          $(this).attr('data-position', (index + 1)).addClass('updated');
        }
      });
      saveNewPositions();
    }
  }).disableSelection();
});

function saveNewPositions() {
  var positions = [];
  $('.updated').each(function() {
    positions.push([$(this).attr('data-index'), $(this).attr('data-position'), $(this).attr('data-type')]);
    $(this).removeClass('updated');
  });

  $.ajax({
    url: SITE_URL + 'standart/islem.php?page=sortable',
    method: 'POST',
    dataType: 'text',
    data: {
      positions: positions,
      pageID: 1,
      // 如果需要把state传给后端,可以在这里添加
      // state: state
    },
    success: function(data) {
      data = data.split(":::", 2);
      var message = data[0],
        answer = data[1];
    }
  });
}

HTML代码(无需修改)

<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>

<ul id="sortable1" class="connectedSortable">
  <li data-index="1" data-position="1">first row</li>
  <li data-index="2" data-position="2">second row</li>
</ul>
<ul id="sortable2" class="connectedSortable">
  <li data-index="1" data-position="1">2. first row</li>
  <li data-index="2" data-position="2">2. second row</li>
</ul>

关键说明

  1. receive事件的作用:当元素从其他Sortable容器拖拽进来时触发,ui.sender指向元素的原父容器,通过对比原容器和当前容器的ID,即可确定拖拽方向并赋值state。
  2. 合并Sortable初始化:避免重复初始化导致的事件冲突,同时为两个容器统一绑定update事件,确保两个列表的位置更新都能被处理。
  3. state的后续使用:如果需要将state传递给后端,可以在saveNewPositions函数中添加对应的参数,或者在receive事件中把state存储为全局变量/元素属性,再在AJAX请求中携带。

内容的提问来源于stack exchange,提问作者user18589150

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 03:36:20