基于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
相关产品推荐
相关产品推荐

