6

我在 jQuery 中创建了一个“2d 滑块”,其中通过在边界框中拖动“句柄”来同时操作 2 个参数。

我通过在父 div 中嵌套一个“句柄”div 并使用 jQuery UI 插件来促进拖动行为来实现这一点。html 看起来像:

<div class="Slider2d" id="grid_spacing_both">
    <div class="Slider2dHandle" id="grid_spacing_both_handle"></div>
</div>

jQuery 看起来像:

$(".Slider2dHandle").draggable({
    containment: "parent",
    scroll: false,
    drag: function(event, ui) {
        // calculates position and updates value input boxes
    }
});

我还创建了一些代码,将句柄重新定位到父 div 中任何点击的位置:

$(".Slider2d").mousedown(function(event){
    // get location of click and reposition handle to click location
});

我想做的是修改上述方法,以便用户可以单击父 div 中的某个位置,将句柄重新定位到单击位置,然后开始拖动句柄而不让鼠标按钮向上。基本上,我需要找到一种以编程方式触发拖动功能的方法。

我在这里这里找到了一些建议,并尝试通过更改上述方法来实施他们的建议,如下所示:

$(".Slider2d").mousedown(function(event){
    // get location of click and reposition handle to click location
    handle = $(".Slider2d").children(".Slider2dHandle");
    handle.trigger(event);
});

这在最技术意义上是有效的,但它超级慢,我从 Safari 收到一堆错误消息,告诉我“RangeError:超出最大调用堆栈大小”。我在想正在发生的是,当我在句柄上触发事件时,它会冒泡到父级,然后再次调用触发器,依此类推。我试图通过在 .trigger() 调用之前和之后将 event.stopPropagation 扔到我的代码中来阻止冒泡,但无济于事。

因此,如果有人对如何使这项工作有任何建议,我将不胜感激。我在这里有一个备用计划,但这在我看来是不必要的复杂。

谢谢!

4

3 回答 3

8

我设法让这个工作。正如我所怀疑的,它与事件处理有关。

修复很简单:我修改了上面的代码来检查事件目标是否与回调绑定的元素(即滑块边界框)相同。在重新定位手柄的初始单击中,这些是相同的元素。但是,当句柄的 mousedown 事件被触发,并且事件冒泡到边界框时,该事件的目标是滑块句柄。因此,它们不匹配,并且不会再次调用触发事件,从而引发无限循环。

至少我认为这就是正在发生的事情。无论如何,这是有效的代码:

$(".Slider2d").mousedown(function(event){
    // get location of click and reposition handle to click location 

    handle = $(".Slider2d").children(".Slider2dHandle");
    if ($(this).attr("id") == $(event.target).attr("id")) {
        handle.trigger(event);
    }
});
于 2011-03-14T21:49:49.300 回答
1

或者您可以在处理程序的 mousedown 事件处停止传播,这样它就不会冒泡到滑块的 mousedown 事件。

$(".Slider2d").mousedown(function(event) {
    // get location of click and reposition handle to click location 

    handle = $(".Slider2d").children(".Slider2dHandle");
    handle.trigger(event);
});

$(".Slider2dHandle").mousedown(function(event) {
    event.stopPropagation();
});
于 2013-02-26T20:30:41.080 回答
0

这对我不起作用,所以我认为我做错了什么。但我想知道,如果它适合你,为什么不设置:

if ($(this).attr("id") == $(event.target).attr("id"))

对此:

if (this === event.target)

一旦我弄清楚这一点,我会更新。

仍然没有:在那个无限循环中,event.target剩下的是滑块,而不是手柄,只有这样,第二个事件才真正被触发。

编辑:知道了,我从 jQuery 1.7.1 切换到 1.6.4 并且它可以工作。

于 2012-03-15T15:08:26.453 回答