当我在jquery UI中取消拖动时如何防止点击事件?

时间:2014-10-10 19:08:22

标签: jquery jquery-ui

我的目的是拥有一系列文件夹和子项(如目录树),然后拖放项目以重新排列。当我只是点击一个文件夹(带有子ul的列表项)时,它应该滑开或滑动关闭。

问题是:我想在取消拖动时阻止点击事件。

取消 - 我的意思是我开始拖动元素,然后释放鼠标而不将其放在任何可放置的顶部。

我的第一个猜测是使用event.stopImmediatePropagation()event.stopPropagation()。当我取消没有ul子项的列表项的拖动时,这确实会阻止click事件。

但是,当我取消对具有ul子项的li的拖动时,会发生默认的单击行为(在本例中为slideToggle)。

当我取消拖动带有ul儿童的li时,如何防止点击事件?

$("li").click(function (event) {
    console.log($(this).attr("class"));
    if ($(this).children("ul").length > 0) $(this).children("ul").slideToggle();
    event.stopPropagation();
    event.stopImmediatePropagation();
    event.preventDefault();
})

$("li").draggable({
    rever: false,
    helper: "clone",
    cursorAt: {
        top: -1,
        left: -1
    },
    stop: function (event) {
        event.stopPropagation();
        event.stopImmediatePropagation();
    }
});

$("span").droppable({
    hoverClass: "ui-state-active",
    greedy: true,
    tolerance: "pointer",
    drop: function (event, ui) {
        var dragged = ui.draggable
        var target = $(this).parent()

        if (target.children("ul").length == 1) {
            dragged.appendTo(target.children("ul"));
        } else {
            // depends upon whether I'm dragging from above or from below
            if (dragged.prev().is(target)) // dragging from below
            dragged.insertBefore(target)
            else dragged.insertAfter(target)
        }

        event.stopPropagation();
    },
});

JSFiddle

中的完整代码

1 个答案:

答案 0 :(得分:1)

一种解决方法是使用单独的元素来触发这两个动作。

例如,我们使用handle选项。

  

如果指定,则限制从开始拖动,除非在指定元素上发生了mousedown。只允许从可拖动元素下降的元素

触发拖动,并使用单独的<span>元素触发切换功能。

Updated Fiddle点击要拖动的文字,+ / -进行切换


另一个 hackish 解决方法是跟踪布尔标志 -

我们可以在拖动开始时将boolean设置为true,并在停止回调中的微小超时后将其设置回false

当我们释放鼠标时会立即触发click事件 - 所以如果通过拖动触发点击,布尔标志仍然是true,因为我们只会在短暂超时后重置它。如果是正常点击 - 该标志将为false。

Updated Fiddle


var dragging = false;
$("li").click(function (event) {
    event.stopPropagation();
    $this = $(this);
    console.log(dragging);
    if (!dragging) {
        if ($this.children("ul").length > 0) $this.children("ul").slideToggle();
    }
});

$("li").draggable({
    revert: false,
    helper: "clone",
    cursorAt: {
        top: -1,
        left: -1
    },
    start: function (event) {
        dragging = true;
    },
    stop: function (event) {
        setTimeout(function () {
            dragging = false;
        }, 10);
    }
});

$("span").droppable({
    hoverClass: "ui-state-active",
    greedy: true,
    tolerance: "pointer",
    drop: function (event, ui) {
        var dragged = ui.draggable
        var target = $(this).parent()

        if (target.children("ul").length == 1) {
            dragged.appendTo(target.children("ul"));
        } else {
            // depends upon whether I'm dragging from above or from below
            if (dragged.prev().is(target)) // dragging from below
            dragged.insertBefore(target)
            else dragged.insertAfter(target)
        }

        event.stopPropagation();
    },
});
.ui-state-active {
     background-color : red;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<ul>
    <li><span>Test 1</span>

    </li>
    <li> <span>Test 2</span>

        <ul>
            <li class="A"><span>Test A</span>

            </li>
            <li class="B"><span>Test B</span>

            </li>
            <li class="C"><span>Test C</span>

            </li>
        </ul>
    </li>
    <li><span>Test 3</span>

    </li>
    <li> <span>Test 4</span>

        <ul>
            <li><span>Test X</span>

            </li>
            <li><span>Test Y</span>

                <ul>
                    <li><span>F</span>

                    </li>
                    <li><span>G</span>

                    </li>
                    <li><span>H</span>

                    </li>
                </ul>
            </li>
            <li><span>Test Z</span>

            </li>
        </ul>
    </li>
</ul>