JQuery 可轻松拖动

Posted

技术标签:

【中文标题】JQuery 可轻松拖动【英文标题】:JQuery draggable with ease 【发布时间】:2011-09-17 22:29:23 【问题描述】:

我想用jquery的可拖动来实现轻松的效果。但是我没有在这个插件中找到该选项。所以我想知道是否有其他插件有这个选项 - 或者一个简单的解决方案。

我想要达到的效果是这样的:http://www.fileden.com/files/2009/6/4/2466215/dragease.swf

如您所见,在拖动时,由于缓动,图像移动感觉更加流畅。我还想将拖动限制在一个轴上,还需要让它恢复到原来的位置。 JQuery 的 draggable 确实有最后两个选项,所以很好。

示例代码已经为我提供了我想要的(除了缓动):http://jsfiddle.net/dandoen/NJwER/1/

任何建议将不胜感激。

干杯, 丹东

【问题讨论】:

【参考方案1】:

您可以使用原始的可拖动,但您需要几行额外的代码。我们创建了一个不可见的助手并手动为原始对象设置动画以使用自定义缓动来跟随它。您可以使用动画持续时间和easing function 来自定义效果。

如果您要使用任何可拖动对象,当鼠标悬停在它们上方时,它们应该会正确激活,而无需等待对象到达那里。

唯一的缺点是,由于我们手动更改原始元素的位置,因此无法使用 revert 参数,但可以通过保存起始位置并在拖动停止时将对象动画返回来轻松解决。

html

<div id="draggable" class="ui-widget-content">
    <p>Revert the original</p>
</div>

CSS:

#draggable 
    position: relative;
    width: 100px;
    height: 100px;
    padding: 0.5em;
    float: left;
    margin: 0 10px 10px 0;
    background-color: red;
    border: 2px solid gray;

javascript

$(function() 
    $("#draggable").draggable(
        // Can't use revert, as we animate the original object
        //revert: true,

        axis: "y",
        helper: function()
            // Create an invisible div as the helper. It will move and
            // follow the cursor as usual.
            return $('<div></div>').css('opacity',0);
        ,
        create: function()
            // When the draggable is created, save its starting
            // position into a data attribute, so we know where we
            // need to revert to.
            var $this = $(this);
            $this.data('starttop',$this.position().top);
        ,
        stop: function()
            // When dragging stops, revert the draggable to its
            // original starting position.
            var $this = $(this);
            $this.stop().animate(
                top: $this.data('starttop')
            ,1000,'easeOutCirc');
        ,
        drag: function(event, ui)
            // During dragging, animate the original object to
            // follow the invisible helper with custom easing.
            $(this).stop().animate(
                top: ui.helper.position().top
            ,1000,'easeOutCirc');
        
    );
);

演示:http://jsfiddle.net/NJwER/4/

更新:约束轴可拖动

根据要求,这是来自this thread 的修改代码。原版是 brianpeiris 的出色的轴约束可拖动扩展。

更改它非常简单,只需将上述位添加到代码中并使其恢复可选。我将它重命名为draggableXYE(E 表示缓和)。它可能不是最优雅的解决方案,将其编写为draggableXY 的小扩展可能很容易,但它会完成这项工作。

当您打开动态模式时,拖动感觉非常有趣,当可拖动对象从一个轴捕捉到另一个轴时,它可以轻松移动。

Javascript:

$.fn.draggableXYE = function(options) 
    var defaultOptions = 
        distance: 5,
        dynamic: false
    ;
    options = $.extend(defaultOptions, options);

    // ADDED: Store startPosition for reverting
    var startPosition = this.position();

    // ADDED: Function to apply easing to passed element
    function AnimateElement(element, newpos) 
        $(element).stop().animate(
            top: newpos.top,
            left: newpos.left
        , 1000, 'easeOutCirc');
    

    this.draggable(
        distance: options.distance,
        // ADDED: Helper function to create invisible helper
        helper: function()
            return $('<div></div>').css('opacity',0);
        ,
        start: function(event, ui) 
            ui.helper.data('draggableXY.originalPosition', ui.position || 
                top: 0,
                left: 0
            );
            ui.helper.data('draggableXY.newDrag', true);
        ,
        drag: function(event, ui) 
            var originalPosition = ui.helper.data('draggableXY.originalPosition');
            var deltaX = Math.abs(originalPosition.left - ui.position.left);
            var deltaY = Math.abs(originalPosition.top - ui.position.top);

            var newDrag = options.dynamic || ui.helper.data('draggableXY.newDrag');
            ui.helper.data('draggableXY.newDrag', false);

            var xMax = newDrag ? Math.max(deltaX, deltaY) === deltaX : ui.helper.data('draggableXY.xMax');
            ui.helper.data('draggableXY.xMax', xMax);

            var newPosition = ui.position;
            if (xMax) 
                newPosition.top = originalPosition.top;
            
            if (!xMax) 
                newPosition.left = originalPosition.left;
            

            // ADDED: Animate original object with easing to new position
            AnimateElement(this, newPosition);

            return newPosition;
        ,
        // ADDED: Stop event to support reverting
        stop: function() 
            if (options.revert) 
                AnimateElement(this, startPosition);
            
        
    );
;

用法:

$('.drag').draggableXYE(
    revert: true,
    dynamic: true
);

演示:http://jsfiddle.net/4C9p2/

【讨论】:

非常感谢!一个小问题,知道如何实现 brianpeiris 的代码link,以便允许用户水平和垂直拖动,但只能在一个轴上。 @dandoen:我添加了带有缓动和可选还原的 brianpeiris 扩展的修改版本。享受吧。 太棒了!!谢谢朋友,希望我能更多地支持你哈哈 我们如何为鼠标事件和触摸事件(在平板电脑/移动设备上)添加相同的功能?? 顺便说一句,辅助函数需要修改,当容器和可拖动元素绝对定位时会导致很多问题,因为辅助函数的位置是相对于视口计算的,我猜。不是返回$('&lt;div&gt;&lt;/div&gt;').css('opacity',0),而是返回$(this).clone().css('opacity',0) 处理所有问题,无论是绝对定位还是相对定位,任何地方。【参考方案2】:

我看到了很多关于缓和/动量的问题。我终于开始从我的解决方案中制作一个插件。在这里试试:

http://jsfiddle.net/mattsahr/bKs7w/

基本使用很简单。

$('.dragme').draggable().dragMomentum();

它整理了this question 的一些早期工作。

注意事项 -- 遏制—— .dragMomentum 与“遏制”选项配合得很好,当你放手时,它会用一个不错的回弹动作代替正常行为。如果没有容器 div,它对浏览器窗口执行相同的从边缘回弹。

兼容性 -- 它适用于 ie9、chrome12、firefox5。过去,我不知道。

【讨论】:

看起来不错。在 MIT 或类似许可下授权如何?【参考方案3】:

我认为 draggable 没有这样的选择。您可能需要自己动手。如果您选择这样做,您可能需要执行以下操作:

http://jsfiddle.net/NJwER/2/

这真的很粗糙(但有点有趣)。您可能希望根据元素与光标的距离来动态设置动画持续时间,并使用默认的缓动。

$(function() 
    var dragging = false;
    var dragger, offsetX, offsetY;

    $("#draggable").mousedown(function(e) 
        dragging = true;
        dragger = this;
        offsetX=e.offsetX;
        offsetY=e.offsetY;
    );

    $("body").mouseup(function(e) 
        dragging = false;
    ).mousemove(function(e) 
        if (dragging) 
            $(dragger).stop().animate(left:e.pageX-offsetX, top:e.pageY-offsetY,300);
            console.log(e.pageX+" "+e.pageY);
        
    );
);​

【讨论】:

我不会根据距离来计时,尤其是如果您使用了 easeOut 功能之一。

以上是关于JQuery 可轻松拖动的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery UI 的可拖动按钮

jquery draggable - 删除拖动元素

拖动时jQuery可拖动克隆大小

滚动可拖动项目的内容时禁用jQuery拖动

带有可点击对象的jQuery可拖动列表 - 防止点击拖动

克隆时的jQuery可拖动元素不可拖动