3

问题

我正在使用SortableJS构建一个可拖动的树组件。这意味着我的每个sortable-items 都有一个toggle-arrow作为打开和关闭 a 的子元素sub-tree(如果有的话)。

如果单击,我正在尝试使用stopPropagation()来阻止选择父级,但它不起作用。sortable-itemtoggle-arrow

关闭时是这样的: 在此处输入图像描述

打开时看起来像这样: 在此处输入图像描述

您在打开状态下看到的蓝色突出显示(第二张图片)是我在使用插件selectedClass时为选项选择的样式。multiDrag

这说明当我单击toggle-arrow它会导致父级sortable-item被选中。

我不希望这种情况发生。

编码

我的 SortableJS 树组件中的项目代码如下所示(使用 Vue.js 和 Pug 语法):

div.sortable-item
    div.content
        div.toggle-arrow(@click.stop="toggleTree($event)")
        div.icon
        div.title
    div.sub-tree

然后我有一个处理我的元素@click绑定的处理程序:toggle-arrow

toggleTree = function($event) {
    $event.stopPropagation()
    /// Code for handling the sub-tree toggling goes here.
    /// The sub-tree toggling itself works just fine.
}

您可以看到我声明@click.stop为事件绑定,这应该阻止click事件从toggle-arrow子元素冒泡,但它不起作用。

我什至试图$event.stopPropagation在处理程序中使用。但是,事件似乎继续冒泡,因此父sortable-item元素最终处于选定状态。

我也尝试过声明@click.native.stop为事件绑定,但它只是阻止我的toggleTree方法触发。我假设在某处有另一个事件处理程序SortableJS干扰@click.native.stop绑定。

问题

  1. 单击my 的子元素时,如何停止事件的传播sortable-item

  2. multiDrag插件如何处理选择?我仔细研究了代码,发现该事件是在 的事件select处理程序中触发dropsortable-item,但我对此感到困惑。为什么要drop使用事件处理程序来切换 a 的选择sortable-item

在此先感谢您提供的任何信息。

4

2 回答 2

4

错误事件

查看 SortableJS 的来源,您似乎想要停止冒泡的事件不是click事件,而是mouseup事件。

在此处输入图像描述

“卡住”拖动项目问题

如该答案的评论中所示,停止mouseup事件传播会导致意外开始拖动并且sortable-item“卡住”指针的问题。

似乎“拖动启动”是由 、 或 事件触发的pointerdownmousedown具体touchstart取决于设备。

可以安全地假设该pointerdown事件是根据 caniuse.com进行触发的事件。

在此处输入图像描述

解决方案

因此,解决此问题的实际方法是使用@pointerdown.stop事件绑定来触发您的toggleTree方法,而不会触发对 的选择sortable-item或无意的拖动启动。

div.sortable-item
    div.content
        div.toggle-arrow(@pointerdown.stop="toggleTree($event)")
        div.icon
        div.title
    div.sub-tree
于 2020-06-01T09:52:39.700 回答
2

改变

div.toggle-arrow(@click.stop="toggleTree($event)")

div.toggle-arrow(@click.native.stop="toggleTree($event)")

如果您所做的toggleTree只是stopPropagation,您可以将其更改为:

div.toggle-arrow(@click.native.stop)

文档

简而言之,您当前正在停止对子组件发出的任何点击的传播(也称为自定义 Vue 事件,它实际上不需要停止传播,因为它默认不会冒泡)。您想要做的是调用event.stopPropagation()本机click事件。
另一种方法是使用:

div.toggle-arrow(@click.native="toggleTree($event)")

...并.stopPropagation()在里面打电话toggleTree。这正是.stop修饰符所做的。

于 2020-06-02T03:33:48.487 回答