jQuery拖拽

思路

  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');
    });

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,467评论 1 11
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,375评论 1 45
  • (续jQuery基础(1)) 第5章 DOM节点的复制与替换 (1)DOM拷贝clone() 克隆节点是DOM的常...
    凛0_0阅读 1,312评论 0 8
  • 总结: 鼠标事件 1.click与dbclick事件$ele.click()$ele.click(handler(...
    阿r阿r阅读 1,592评论 2 10
  • 本篇博客源地址 总结: 鼠标事件 1.click与dbclick事件ele.click()ele.click(ha...
    ZombieBrandg阅读 664评论 0 1