• div拖拽的问题


    今天看到一篇写的很好的文章,摘抄如下:

    思路

    1. 父盒子相对定位,子元素,也就是被拖拽的元素绝对定位
    2. 当鼠标在子元素中按下时,绑定鼠标移动事件,根据鼠标位置改变元素位置
      • 设置鼠标当前位置(offsetX,offsetY,这时和父的相对位置)为元素的中心位置
      • 移动时改变位置css中的left为offsetX...的位置
    3. 当鼠标离开时,解绑鼠标移动事件

    实现过程(一)

    css 部分

     .decision-box{
                position: relative;
                width: 1500px;
                height: 600px;
                border: 1px solid #000;
                border-radius: 6px;
                /*margin-left: -40px;*/
            }
            .item{
                position: absolute;
                width: 50px;
                height: 30px;
                background: green;
                border-radius: 6px;
                text-align: center;
                line-height: 30px;
                cursor: pointer;
                left: 50px
            }
    

    html 部分

    <div class="decision-box decision_box">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
    

    js 部分

     //鼠标按下,要在移动元素上按下
        $(document).on('mousedown','.decision_box .item',function(e){
            var ele = $(e.target);
            $(document).on('mousemove','.decision_box',function(e){
                //移动鼠标时改变元素位置
                var x = e.offsetX,
                    y = e.offsetY;
                ele.css({
                    left:x - 25 + 'px',
                    top:y - 15  + 'px'
                });
                e.stopPropagation();
            });
            e.stopPropagation();
        });
        //鼠标放开
        $(document).on('mouseup',function(){
            //解除鼠标移动事件
            $(document).off('mousemove');
        });
    

    这时,发生了错误,元素一闪一闪的,位置不是一直跟着鼠标,在mousemove触发函数里打印一下位置,发现位置不一直是鼠标位置。原来是应为鼠标位置offsetX的原因。

    关于鼠标位置

    • clientX 相对于可是窗口的距离
    • offsetX 相对于e.target元素的位置
    • pageX 相对于文档的左边缘
    • screenX 相对于屏幕的位置

    原来offsetX是相对于e.target元素的位置。加入被拖拽元素宽高100px,当我点击100px,100px时,元素的中心位置变为100,100;此时offsetX又变为了50;这时offsetX又变回100;(以上数字只是数字,因为有移动)。如上,就形成了一闪一闪,之后鼠标会超过元素范围,这时,元素位置就在鼠标相对于本身和鼠标相对于父盒子之间切换。

    那么怎么解决这个问题呢?我的思路是:

    • 使用其它鼠标位置,当点击元素时获取位置作为初始位置
    • 当移动时获取位置并求出相对位移,这个相对于位移也就是元素要移动的距离。

    实现过程(二)

    js 部分

    //鼠标按下,要在移动元素上按下
        $(document).on('mousedown','.decision_box .item',function(e){
            console.log(parseInt($(e.target).css('left')))
            var ele = $(e.target);
            var initX = e.clientX,
                initY = e.clientY,
                itemX = parseInt(ele.css('left'));
                itemY = parseInt(ele.css('top'));
            $(document).on('mousemove','.decision_box',function(e){
                //移动鼠标时改变元素位置
                var curX = e.clientX,
                    curY = e.clientY;
                ele.css({
                    left:itemX + (curX - initX) + 'px',
                    top:itemY + (curY - initY) + 'px'
                });
                e.stopPropagation();
            });
            e.stopPropagation();
        });
        //鼠标放开
        $(document).on('mouseup',function(){
            //解除鼠标移动事件
            $(document).off('mousemove');
        });
    

    成功,可以拖动了,这时又遇上了一个问题,当拖动元素时,有其它文本别选中时,拖拽又出现了bug,这时就要用到下面面这两个属性

    onselectstart = "return false";
    onselect = "return false";
    
    • onselectstart事件不被input和textarea标签支持,而onselect事件只被input和textarea支持。
    • Firefox/Opera不支持onselectstart事件Firefox中可以使用CSS "-moz-user-select:none"属性来禁止文本选定
    • webkit浏览器可以使用“-khtml-user-select”,当然也可以使用onselectstart事件来阻止用户选定元素内文本,如下
    <div onselectstart="return false">accc</div>
    

    这个属性意思就是不让文本被选中。要做的就是当点击元素时,上这个属性,当放开鼠标时去掉这个属性(改成return true);

    最后代码

      //鼠标按下,要在移动元素上按下
        $(document).on('mousedown','.decision_box .item',function(e){
            $('body').attr('onselectstart','return false');
            console.log(parseInt($(e.target).css('left')))
            var ele = $(e.target);
            var initX = e.clientX,
                initY = e.clientY,
                itemX = parseInt(ele.css('left'));
                itemY = parseInt(ele.css('top'));
            $(document).on('mousemove','.decision_box',function(e){
                //移动鼠标时改变元素位置
                var curX = e.clientX,
                    curY = e.clientY;
                ele.css({
                    left:itemX + (curX - initX) + 'px',
                    top:itemY + (curY - initY) + 'px'
                });
                e.stopPropagation();
            });
            e.stopPropagation();
        });
        //鼠标放开
        $(document).on('mouseup',function(){
            $('body').attr('onselectstart','return true');
            //解除鼠标移动事件
            $(document).off('mousemove');
        });
    

    这时,选中文本后再进行拖拽还有问题,(也可不解决)我暂时不知道;还有碰撞检测什么的也没加。待续......

    https://www.jianshu.com/p/bd6e4f6122cf

  • 相关阅读:
    Java学习之IO之File类一
    Java学习之二分查找算法
    Java学习之国际化程序
    Java学习之自定义异常
    Java学习之开篇—个人随想
    pl/sql 的 put和put_line区别
    Java中static、final用法
    一个包含所有c++的头文件的头文件
    Codeforces Round #379 (Div. 2)
    hdu-5977 Garden of Eden(树分治)
  • 原文地址:https://www.cnblogs.com/sweeeper/p/11525703.html
Copyright © 2020-2023  润新知