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

基于Shopify Draggable的类Trello视图:分类与任务拖拽冲突解决

解决Shopify Draggable中分类与任务拖拽的干扰问题

嘿,我完全懂你遇到的困扰——当同时启用分类(.category-swap)和任务(li)的Sortable功能后,拖拽任务时会意外触发分类的排序操作,这本质是事件冒泡导致的:任务元素是分类元素的子节点,拖拽任务的事件会向上冒泡到父级的分类Sortable实例,让它误以为你要拖拽分类。

好在Shopify Draggable提供了优雅的解决方案,下面给你两种可行的处理方式:

方案一:使用cancel选项阻止任务触发分类拖拽

给分类的Sortable实例添加cancel参数,明确指定任务元素为“不可触发分类拖拽”的节点,这样拖拽任务时就不会干扰分类的排序逻辑:

// task sortable
const sortable = new Draggable.Sortable(document.querySelectorAll('ul'), {
  draggable: 'li',
});

// cat sortable - 添加cancel选项
const sortableCat = new Draggable.Sortable(document.querySelectorAll('.main-div'), {
  draggable: '.category-swap',
  cancel: '.todo-list li' // 点击任务时不触发分类拖拽
});

方案二:使用handle选项限制分类拖拽的触发区域

如果你希望只有点击分类的特定区域(比如头部标题)才能拖拽分类,可以用handle选项指定触发拖拽的元素,这样任务区域的拖拽操作就不会影响分类:

// task sortable
const sortable = new Draggable.Sortable(document.querySelectorAll('ul'), {
  draggable: 'li',
});

// cat sortable - 添加handle选项
const sortableCat = new Draggable.Sortable(document.querySelectorAll('.main-div'), {
  draggable: '.category-swap',
  handle: '.card-header' // 仅点击分类头部时可拖拽分类
});

完整可运行代码示例

下面是整合了方案二的完整代码,你可以直接测试:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://adminlte.io/themes/v3/dist/css/adminlte.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.3/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@shopify/draggable@1.0.0-beta.11/lib/draggable.bundle.js"></script>
<html>
<head></head>
<body>
<div class="row main-div">
  <div class="col-md-2 category-swap">
    <div class="card">
      <div class=" card-header">
        <h5 class="card-title">Cat 1</h5>
      </div>
      <ul class="todo-list" data-widget="todo-list">
        <li>Task 1</li>
        <li>Task 2</li>
        <li>Task 3</li>
        <li>Task 4</li>
      </ul>
    </div>
  </div>
  <div class="col-md-2 category-swap">
    <div class="card">
      <div class=" card-header">
        <h5 class="card-title">Cat 2</h5>
      </div>
      <ul class="todo-list" data-widget="todo-list">
        <li>Task 1</li>
        <li>Task 2</li>
        <li>Task 3</li>
        <li>Task 4</li>
      </ul>
    </div>
  </div>
  <div class="col-md-2 category-swap">
    <div class="card">
      <div class=" card-header">
        <h5 class="card-title">Cat 3</h5>
      </div>
      <ul class="todo-list" data-widget="todo-list">
        <li>Task 1</li>
        <li>Task 2</li>
        <li>Task 3</li>
        <li>Task 4</li>
      </ul>
    </div>
  </div>
  <div class="col-md-2 category-swap">
    <div class="card">
      <div class=" card-header">
        <h5 class="card-title">Cat 4</h5>
      </div>
      <ul class="todo-list" data-widget="todo-list">
        <li>Task 1</li>
        <li>Task 2</li>
        <li>Task 3</li>
        <li>Task 4</li>
      </ul>
    </div>
  </div>
</div>
<script>
// task sortable
const sortable = new Draggable.Sortable(document.querySelectorAll('ul'), {
  draggable: 'li',
});

// cat sortable - 仅允许点击分类头部拖拽
const sortableCat = new Draggable.Sortable(document.querySelectorAll('.main-div'), {
  draggable: '.category-swap',
  handle: '.card-header'
});
</script>
</body>
</html>

这两种方案都能有效区分分类和任务的拖拽操作,推荐方案二,因为它更符合用户的直觉——通常用户只会点击分类标题来移动整个分类,而任务区域只用来拖拽任务本身。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 17:03:15