【问题标题】:Best way of making draggable element jump to cursor (and start drag) when mousedown on parent当鼠标按下父级时使可拖动元素跳转到光标(并开始拖动)的最佳方法
【发布时间】:2013-05-02 08:49:17
【问题描述】:

我有一个用 jQuery UI 的draggable() 函数制作的自制滑块:

$("#petrolGauge .fuelBar .slider").draggable({
    containment: "parent",
    axis: "x",
    drag:function(){
        updValues();
    },
    start:function(){
        $(this).css("background-color","#666");
    },
    stop:function(){
        //checkForm();
        $(this).css("background-color","#AAA");
    }
});

这是用于以下标记:

<div id="petrolGauge">
    <input id="endPet" name="endPet" type="hidden" value="0">
    How much fuel was left in the tank when you were finished? (Use the slider) <b>(~<span class="petLeft">0</span>%)</b>
    <span class="mandatory">*</span><br />
    <div class="fuelBar">
        <div title="Drag" class="slider"></div>
    </div>

当我单击滑块时,这是一种享受。但我希望这样当我单击燃料栏(滑块的父级)时,滑块不仅开始拖动,而且还跳转到光标。我通过这样做实现了它:

$("#petrolGauge .fuelBar").on("mousedown",function(e){
    slider = $("#petrolGauge .fuelBar .slider");
    left = e.pageX-($(this).offset().left)-(slider.width()/2);
    updValues();
    slider.css("left",left).trigger(e);
});

这有两个问题:

首先,当单击父级时,我会在滑块开始拖动之前延迟几秒钟?我已经在 Chrome 和 IE 中尝试并测试了它,并且都做到了。其次,如果光标距离父项边缘的距离小于滑块宽度的一半,则滑块将移动到父项的外部。通过几次检查来解决这个问题并不难,但想知道是否还有其他方法?老实说,我很惊讶draggable() 没有任何参数。如果可以的话,我不想使用slider(),但如果这是唯一的方法,那么它就是唯一的方法。

这里有一个 fiddle 可以使用。

【问题讨论】:

    标签: javascript jquery html slider draggable


    【解决方案1】:

    您得到延迟的原因是因为您在.on() 事件中使用了.trigger(),这会创建一个大循环。结果,循环减慢了移动过程。

    $("#petrolGauge .fuelBar").click(function (e) { // use click instead of mousedown
        slider = $("#petrolGauge .fuelBar .slider");
        left = e.pageX - ($(this).offset().left) - (slider.width() / 2);
        if(left > 570) { left = 570; } else if(left < 0) { left = 0; }
        // it looks like a draggable bug due to the manual position change, so use a small check
        slider.css("left", left); // change the position first
        updValues();              // then calculate and update the div 
        // no need to trigger the event a second time because it will loop until jQuery exceeds it's trigger limit.
    });
    

    这是更新后的FIDDLE

    更新答案

    要使.slider在不直接拖动时随着鼠标移动而移动,请将mousemove事件绑定到mousedown并在mouseup时取消绑定。然后在.mousemove() 中更改.slider 的位置。

    var move = function (e) {
        left = e.pageX - ($('#petrolGauge .fuelBar').offset().left) - (slider.width() / 2);
        if (left > 570) {
            left = 570;
        } else if (left < 0) {
            left = 0;
        }
        slider.css("left", left);
        updValues();
    };
    var slider = $("#petrolGauge .fuelBar .slider");
    $("#petrolGauge .fuelBar").mousedown(function (e) {
        e.preventDefault();
        left = e.pageX - ($(this).offset().left) - (slider.width() / 2);
        if (left > 570) {
            left = 570;
        } else if (left < 0) {
            left = 0;
        }
        slider.css("left", left)
        $(this).bind('mousemove', move);
        updValues();
    }).mouseup(function () {
       $(this).unbind('mousemove');
    });
    

    【讨论】:

    • 谢谢你很好地解释了循环,这让我错过了。我真的不想使用点击,因为我的想法是让它变得漂亮和流畅。我不希望用户先按下鼠标然后再按下鼠标然后继续调整。
    • 是的.. 完全一样。更新您的答案,我会接受。谢谢。
    • 很高兴它成功了,不幸的是我不知道为什么.slider 会移出它的parent,但我猜这是手动移动.slider 产生的错误。无论如何,这可以通过条件语句轻松解决。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    相关资源
    最近更新 更多