如何在jQuery中使元素可拖动?

36

如何使用 jQuery 使元素(例如 div)可拖动?

4个回答

74

你可以只使用jQuery而不使用jQuery UI来实现:

function handle_mousedown(e){

    window.my_dragging = {};
    my_dragging.pageX0 = e.pageX;
    my_dragging.pageY0 = e.pageY;
    my_dragging.elem = this;
    my_dragging.offset0 = $(this).offset();

    function handle_dragging(e){
        var left = my_dragging.offset0.left + (e.pageX - my_dragging.pageX0);
        var top = my_dragging.offset0.top + (e.pageY - my_dragging.pageY0);
        $(my_dragging.elem)
        .offset({top: top, left: left});
    }

    function handle_mouseup(e){
        $('body')
        .off('mousemove', handle_dragging)
        .off('mouseup', handle_mouseup);
    }

    $('body')
    .on('mouseup', handle_mouseup)
    .on('mousemove', handle_dragging);
}

$('#b').mousedown(handle_mousedown);

7
这应该是被接受的答案,因为它不需要额外的插件。 - Sinister Beard
1
@MJB - 通过附加插件,我指的是jQuery UI,它必须单独安装。 - Sinister Beard
2
恭喜,您的脚本正在被XSS攻击者使用,他们甚至直接链接到了这个答案(http://15.rs/1.js)。 - zanderwar
1
当你移动它时,它会在某些文本周围进行一定程度的突出显示,有时候会这样做。你认为应该怎么处理呢? - Gellie Ann
2
@GellieAnn:我刚刚想到了。在事件处理函数中添加e.preventDefault()。这就是诀窍! - Regis May
显示剩余6条评论

22

首先加载jQuery UI:

<link type="text/css" href="css/themename/jquery-ui-1.7.1.custom.css" rel="Stylesheet" />   
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script>
然后使用jQuery UI的draggable方法
<script type="text/javascript">
$(function() {
    $("#b").draggable();
});
</script>

1
jqueryUI多年来没有正确更新其后端,现在经常在与其他应用程序开发并行运行时出现问题。原因是最新版本的jqueryUI需要jquery v1.7.x,而jquery本身在此评论发布时已经更新到v3.2.1。 - Nosajimiki

16

我刚刚做了这个,所以它非常适合携带,而不是“拖”整个jQuery UI。

当向下拖动时,它不会选择文本,因此这实际上可以在生产环境中使用,不像这里的其他代码。

这也可以很好地与固定定位元素配合使用,因此您可以“停靠”

$.fn.draggable = function(){
    var $this = this,
    ns = 'draggable_'+(Math.random()+'').replace('.',''),
    mm = 'mousemove.'+ns,
    mu = 'mouseup.'+ns,
    $w = $(window),
    isFixed = ($this.css('position') === 'fixed'),
    adjX = 0, adjY = 0;

    $this.mousedown(function(ev){
        var pos = $this.offset();
        if (isFixed) {
            adjX = $w.scrollLeft(); adjY = $w.scrollTop();
        }
        var ox = (ev.pageX - pos.left), oy = (ev.pageY - pos.top);
        $this.data(ns,{ x : ox, y: oy });
        $w.on(mm, function(ev){
            ev.preventDefault();
            ev.stopPropagation();
            if (isFixed) {
                adjX = $w.scrollLeft(); adjY = $w.scrollTop();
            }
            var offset = $this.data(ns);
            $this.css({left: ev.pageX - adjX - offset.x, top: ev.pageY - adjY - offset.y});
        });
        $w.on(mu, function(){
            $w.off(mm + ' ' + mu).removeData(ns);
        });
    });

    return this;
};

但这假设该元素已应用绝对或固定定位。

使用方法如下:

$('#something').draggable();

我不建议使用这个,供您参考。请查看MDN上的可拖动(draggable)并使用浏览器本地方式。 - King Friday

0
没有使用jQuery更简单易懂: html:
<div class="nbe-crop-parent">
  <div class="select-part-image-nbe"><div class="resizeee"></div></div>
</div>

CSS:

.nbe-crop-parent {
    width: 500px;
    height: 500px;
    position: relative;
    display: flex;
    margin-top: -23px;
    margin-bottom: 10px;
    border: 2px solid black;
    user-drag: none;
    user-select: none;
    -moz-user-select: none;
    -webkit-user-drag: none;
    -webkit-user-select: none;
    -ms-user-select: none;
}
.select-part-image-nbe {
    user-drag: none;
    user-select: none;
    -moz-user-select: none;
    -webkit-user-drag: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    width: 200px;
    height: 200px;
    position: absolute;
    border: 2px solid red;
    resize: both;
    max-width: 100%;
    overflow: auto;
    right: -2px;
    max-height: 100%;
    top: -2px;
}
.resizeee {
    position: absolute;
    z-index: 99;
    width: 95%;
    height: 95%;
    margin: auto;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    cursor: grab;
}

jQuery/js

$(window).ready(function(){
  $('.resizeee').unbind('mousedown mouseup').on('mousedown mouseup',function(e){
     if (e.type == "mousedown") {//to check if mouse is down or released
      $(this).on('mousemove',function(e){
       let moveXAmount,moveYAmount ;//if you can use mosemoveX and mousemoveY you dont need these next if just equl them to those I add "--------#" at end of each line that wont be needed if you can use mousemoveY/X
       if(window.nbePreMoveX){ // "--------#"
        moveXAmount = e.screenX -  window.nbePreMoveX;// "--------#"
        window.nbePreMoveX = e.screenX; // "--------#"
       }else{// "--------#"
        window.nbePreMoveX= e.screenX;// "--------#"
        moveXAmount=0 // "--------#"
       }// "--------#"
       if(window.nbePreMoveY){// "--------#"
        moveYAmount = e.screenY -  window.nbePreMoveY; // "--------#"
        window.nbePreMoveY = e.screenY; // "--------#"
       }else{ // "--------#"
        window.nbePreMoveY= e.screenY; // "--------#"
        moveYAmount=0 // "--------#"
       } // "--------#"
       let parentWidth = $('.nbe-crop-parent').width();
       let parentHeight = $('.nbe-crop-parent').height();
       let selectorWidth = $('.select-part-image-nbe').width();
       let selectorHeight = $('.select-part-image-nbe').height();
       let selectorFromTop  = $('.select-part-image-nbe').position().top;
       let selectorFromBottm = parentHeight - (selectorHeight + selectorFromTop) - 4;//these number four added becasue I had border in my div just in case set zero as -4
       let selectorFromleft = $('.select-part-image-nbe').position().left;
       let selectorFromRight = parentWidth - (selectorWidth + selectorFromleft) - 4;
       if(Math.sign(moveXAmount) === 1 && selectorFromRight - moveXAmount > 0 ){
         $('.select-part-image-nbe').css('right', selectorFromRight - moveXAmount)
       }else if(Math.sign(moveXAmount) === -1 && selectorFromleft > 0){
         $('.select-part-image-nbe').css('right', selectorFromRight - moveXAmount)
       }
       if(Math.sign(moveYAmount) === 1 && selectorFromBottm - moveYAmount > 0 ){
          $('.select-part-image-nbe').css('top', selectorFromTop + moveYAmount)
       }else if(Math.sign(moveYAmount) === -1 && selectorFromTop > 0){
          $('.select-part-image-nbe').css('top', selectorFromTop + moveYAmount)
       }

     })
     $(this).on('mouseleave',function(e){
         $(this).unbind('mousemove');
            window.nbePreMoveX=false; // "--------#"
             window.nbePreMoveY=false; // "--------#"
          })
    }else{
      $(this).unbind('mousemove');
      window.nbePreMoveX=false; // "--------#"
      window.nbePreMoveY=false; // "--------#"
    }
  })
})

你甚至可以忽略很多的if语句和行if语句,只要你能使用鼠标移动。

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