在jQuery中拖动后防止点击事件

13
我有一个可拖动的
元素,有一个点击事件但没有任何拖动事件,但是在我拖动
元素后,点击事件会被应用于
元素。如何在拖动后防止点击事件?

如何在拖动后防止点击事件?

$(function(){
    $('div').bind('click', function(){
        $(this).toggleClass('orange');
    });

    $('div').draggable();
});

http://jsfiddle.net/prince4prodigy/aG72R/


这可能会有所帮助:https://dev59.com/P3A75IYBdhLWcg3wFEwI - Simon Steinberger
请注意在加载时div的x和y位置。 检查div是否已移动。 如果是,请删除您分配的样式。 - HIRA THAKUR
请查看我的解决方案(比本帖中的任何解决方案都要简单得多)https://dev59.com/zXI-5IYBdhLWcg3wm5lG#58836706 - Andrey
8个回答

26

先绑定可拖动事件,再绑定点击事件:

$(function(){
    $('div').draggable();
    $('div').click(function(){
        $(this).toggleClass('orange');
    });
});

在这里尝试一下: http://jsfiddle.net/aG72R/55/


3
我认为这是最好的答案。 - MightyPork
3
这应该是被接受的解决方案,这就是它预期的工作方式。演示链接:http://jsfiddle.net/dAL5v - Jean-Philippe Pellet

13

使用ES6类(无需jQuery)

要在JavaScript中实现此操作而不需要jQuery的帮助,可以添加和删除事件处理程序。

首先创建将添加到事件侦听器中并将被移除的函数。

flagged () {
    this.isScrolled = true;
}

并且这将停止事件上的所有事件

preventClick (event) {
    event.preventDefault();
    event.stopImmediatePropagation();
}

接着,在mousedownmousemove事件依次触发时添加标志。

element.addEventListener('mousedown', () => {
    element.addEventListener('mousemove', flagged);
});

记得在鼠标松开时移除此事件监听器,以免在该元素上重复触发大量事件。

element.addEventListener('mouseup', () => {
    element.removeEventListener('mousemove', flagged);
});

最后,在我们的元素上的mouseup事件中,我们可以使用标志逻辑来添加和删除点击。

element.addEventListener('mouseup', (e) => {
    if (this.isScrolled) {
        e.target.addEventListener('click', preventClick);
    } else {
        e.target.removeEventListener('click', preventClick);
    }
    this.isScrolled = false;
    element.removeEventListener('mousemove', flagged);
});
在上面的例子中,我正在针对被单击的实际目标进行定位,因此如果这是一个滑块,我将针对图像而不是主要的库元素进行定位。要定位主要的 元素,只需像这样更改添加/删除事件侦听器即可。
element.addEventListener('mouseup', (e) => {
    if (this.isScrolled) {
        element.addEventListener('click', preventClick);
    } else {
        element.removeEventListener('click', preventClick);
    }
    this.isScrolled = false;
    element.removeEventListener('mousemove', flagged);
});

结论

通过将匿名函数设置为const,我们无需绑定它们。同样,这样它们也有了一个“句柄”,允许我们从事件中删除特定的函数,而不是整个事件集合上的所有函数。


1
在我搜索的所有10个stackoverflow链接和数小时的测试中,这是唯一有效的解决方案。因为我没有像其他人一样使用jQuery...非常感谢! - João Vilaça
THANKS 对我而言非常好用!我已经在我的轻量级JS滑块https://github.com/hrsetyono/hSlider上实现了它。 - hrsetyono

6

我使用了 datasetTimeout 制作了一个解决方案。也许比辅助类更好。

<div id="dragbox"></div>

并且

$(function(){
    $('#dragbox').bind('click', function(){
        if($(this).data('dragging')) return;
        $(this).toggleClass('orange');
    });

    $('#dragbox').draggable({
        start: function(event, ui){
            $(this).data('dragging', true);
        },
        stop: function(event, ui){
            setTimeout(function(){
                $(event.target).data('dragging', false);
            }, 1);
        }
    });
});

请查看示例代码


2

这应该可以工作:

$(function(){

    $('div').draggable({
    start: function(event, ui) {
        $(this).addClass('noclick');
    }
});

$('div').click(function(event) {
    if ($(this).hasClass('noclick')) {
        $(this).removeClass('noclick');
    }
    else {
        $(this).toggleClass('orange');
    }
});
});

DEMO


2
你可以不使用jQuery UI draggable来实现。只需要使用普通的“click”和“dragstart”事件:
$('div').on('dragstart', function (e) {
  e.preventDefault();
  $(this).data('dragging', true);
}).on('click', function (e) {
  if ($(this).data('dragging')) {
    e.preventDefault();
    $(this).data('dragging', false);
  }
});

0

使用React

这段代码适用于React用户,在鼠标抬起时检查draggedRef。

我没有使用点击事件。点击事件由鼠标抬起事件检查。

const draggedRef = useRef(false);

...

<button
  type="button"
  onMouseDown={() => (draggedRef.current = false)}
  onMouseMove={() => (draggedRef.current = true)}
  onMouseUp={() => {
    if (draggedRef.current) return;

    setLayerOpened(!layerOpened);
  }}
>
  BTN
</button>


0
你可以检查 jQuery UI 的 ui-draggable-dragging 类是否存在于可拖动元素上。如果存在,则停止点击事件,否则继续执行。jQuery UI 会自动处理设置和移除该类,因此您无需操心。:)

代码:

$(function(){
    $('div').bind('click', function(){
        if( $(this).hasClass('ui-draggable-dragging') ) { return false; }
        $(this).toggleClass('orange');
    });

    $('div').draggable();
});

我没有看到那个类。 - sebhaase

0

我也遇到了相同的问题(尽管使用的是p5.js),我通过使用全局变量lastDraggedAt解决了它,当拖动事件运行时它会更新。在点击事件中,我只需要检查上次拖动是否早于0.1秒。

function mouseDragged() {
    // other code
    lastDraggedAt = Date.now();
}

function mouseClicked() {
    if (Date.now() - lastDraggedAt < 100)
        return; // its just firing due to a drag so ignore
    // other code
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接