1、为要被拖移六个事件,onmousedown,onmousemove,onmouseup
2、在onmousemove事件中来拍卖被拖移成分的职位的生成,其实轻易成分要活动的距离就是鼠标一回活动之间的离开。
3、个中还包含setCapture,releaseCapture,目标正是为了被搬移的成分始终能抱有核心。
以前差十分的少正是在此以前的认识,能够参见 JS拖动技巧— 关于setCapture
那一个实现,后来趁着职业要求的滋长,做的做事都以要跨浏览器的,所以就再一次思量并参照一些开源代码做了完成。
至今光景思路可剖判为以下几步,小编逐个为你显示。
1、
我们是为着拖移而搬移吗?当然不是,如google地图,当每一遍搬移后她的指标是为着总括当前空间坐标来加载地理音讯。所以本人这里设计了多少个常见事件。以下是事件列表
onDragStart
:成分发生拖移时,要是注册该事件,触发时会接收到多个参数x,y分别为被搬移成分发生拖移时的坐标
onDrag :
成分拖移进程中,若是注册该事件,触发时会接收到八个参数nx,ny拖移进度中坐标产生的偏移量
onDragEnd
:成分发生截止时,若是注册该事件,触发时会接收到五个参数x,y分别为被搬移成分的此时此刻坐标
2、
onmousedown事件应该绑定给何人?在此之前自个儿都是绑定给被拖移成分的,后来意识很不利索,今后设计为可绑定给自由不相干的因素同有难点候完成该因素的拖动。
3、
怎么着来贯彻要素搬移进程中央直属机关接有着宗旨?因为要跨浏览器,所以就不再用setCapture之类的艺术,这里换种沉思,为何成分成分搬移进度中从未了宗旨呢,首如若大家把onmousemove事件注册到了被拖移的要素上,而那实际不是必需的,所以当成分触发onmousedown事件后,小编把onmousemove、onmouseup事件一向登记到document上,那样鼠标移到哪都会有关键。
说完了那样多,直接看代码结构吧!

此番来做一个拖动排序,带有动画效果,先上效果图,不熟谙拖动api的能够查看链接

getBoundingClientRect() 来博取页面成分的职位

getBoundingClientRect() 来获得页面成分的职责

复制代码 代码如下:

图片 1

复制代码 代码如下:

复制代码 代码如下:

Drag = {
obj: null,
init: function (options) {
options.handler.onmousedown = this.start;
options.handler.root = options.root || options.handler;
var root = options.handler.root;
root.onDragStart = options.dragStart || new Function();
root.onDrag = options.onDrag || new Function();
root.onDragEnd = options.onDragEnd || new Function();
},
start: function (e) {//此时的this是handler
var obj = Drag.obj = this;
obj.style.cursor = ‘move’;
e = e || Drag.fixEvent(window.event);
ex = e.pageX;
ey = e.pageY;
obj.lastMouseX = ex;
obj.lastMouseY = ey;
var x = obj.root.offsetLeft;
var y = obj.root..offsetTop;
obj.root.style.left = x + “px”;
obj.root.style.top = y + “px”;
document.onmouseup = Drag.end;
document.onmousemove = Drag.drag;
obj.root.onDragStart(x, y);
},
drag: function (e) {
e = e || Drag.fixEvent(window.event);
ex = e.pageX;
ey = e.pageY;
var root = Drag.obj.root;
var x = root.style.left ? parseInt(root.style.left) : 0;
var y = root.style.top ? parseInt(root.style.top) : 0;
var nx = ex – Drag.obj.lastMouseX + x;
var ny = ey – Drag.obj.lastMouseY + y;
root.style.left = nx + “px”;
root.style.top = ny + “px”;
Drag.obj.root.onDrag(nx, ny);
Drag.obj.lastMouseX = ex;
Drag.obj.lastMouseY = ey;
},
end: function (e) {
var x = Drag.obj.root.style.left ? parseInt(Drag.obj.root.style.left) :
0;
var y = Drag.obj.root.style.top ? parseInt(Drag.obj.root.style.top) :
0;
Drag.obj.root.onDragEnd(x, y);
document.onmousemove = null;
document.onmouseup = null;
Drag.obj = null;
},
fixEvent: function (e) {
e.pageX = e.clientX + document.documentElement.scrollLeft;
e.pageY = e.clientY + document.documentElement.scrollTop;
return e;
}
}

效果图

document.documentElement.getBoundingClientRect

document.documentElement.getBoundingClientRect

地点init首要管理部分初如化专门的学业,如记录onDragStart、onDrag、onDragEnd三个事件,
handler为管理拖动事件的可怜成分,root为被拖动的因素。
当在handler上点击后触发Drag.start方法,Drag.start重要为记录住鼠标相对整个页面包车型大巴职责;给document注册onmouseup、onmousemove事件,及触发onDragStart事件。
Drag.drag方法也很简短,主要功用便是翻新被搬移成分地方,同不常间记录住鼠标相对整个页面包车型大巴地点。
Drag.end方法就更简短了,就是做一些竣事工作。

在线演示:http://jsrun.net/XpiKp/edit

该格局再次回到多个对象,从而得到页面中有些成分的左,上,右和下分别针锋相对浏览器视窗的岗位,即分别表示该因素上、左、右、下四条边界相对于浏览器窗口左上角(注意,不是文书档案区域的左上角)的撼动像素值。并且该办法已经不复是IE
Only了,FF3.0+和Opera9.5+已经支持了该措施,能够说在赢得页面成分地点上效用能有非常大的拉长,所以取得页面上有个别成分相对于浏览器窗口的偏移量就成了getBoundingClientRect的用武之地了,遵照一篇作品的布道,it’s
awsome,太帅了=。=因为不必纠结于offset、pagex、clientx等等等等等等。在原先版本的Opera和Firefox中必得透过轮回来获得成分在页面中的相对地方。
图片 2 
图片 3 
代码示例:

该方式重返贰个对象,进而获得页面中某些成分的左,上,右和下各自针锋相对浏览器视窗的岗位,即分别表示该因素上、左、右、下四条边界相对于浏览器窗口左上角(注意,不是文书档案区域的左上角)的撼动像素值。并且该办法已经不复是IE
Only了,FF3.0+和Opera9.5+已经辅助了该措施,能够说在取得页面成分地点上效用能有十分的大的增高,所以获得页面上有些元素相对于浏览器窗口的偏移量就成了getBoundingClientRect的用武之地了,根据一篇小说的传教,it’s
awsome,太帅了=。=因为不必纠结于offset、pagex、clientx等等等等等等。在在此之前版本的Opera和Firefox中必需通过轮回来获得成分在页面中的相对地方。
图片 4 
图片 5 
代码示例:

最终给大家附段使用的代码吧,祝大家学习欢喜!

思路(先不思虑动画)

种种li既是可拖动,同期也是容器,拖动到li上面时移动拖动的li。
先把html写好

<ul>
        <li class="ele" draggable="true">1</li>
        <li class="ele" draggable="true">2</li>
        <li class="ele" draggable="true">3</li>
        <li class="ele" draggable="true">4</li>
        <li class="ele" draggable="true">5</li>
        <li class="ele" draggable="true">6</li>
        <li class="ele" draggable="true">7</li>
        <li class="ele" draggable="true">8</li>
    </ul>

css

ul {
        list-style: none;
        margin: 200px;
        font-size: 0;
    }
    .ele {
        font-size: 16px;
        width: 100px;
        height: 40px;
        border: 1px solid #999;
        background: #EA6E59;
        margin: 2px 0;
        border-radius: 10px;
        padding-left: 10px;
        color: white;
        cursor: move;
    }

上边增加事件,由于拖动是实时的,所以并未有利用drop而是选取了dragover。并且用一个变量来保存当前拖动的成分。这里一向动用事件委托,直接使用ul来监听

var node = document.querySelector("#container");
var draging = null;
//使用事件委托,将li的事件委托给ul
node.ondragstart = function(event) {
    /firefox设置了setData后元素才能拖动!!!!
        event.dataTransfer.setData("te", event.target.innerText); //不能使用text,firefox会打开新tab
        draging = event.target;
    }
node.ondragover = function(event) {
        event.preventDefault();
        var target = event.target;
    //因为dragover会发生在ul上,所以要判断是不是li
        if (target.nodeName === "LI"&&target !== draging) {
                //_index是实现的获取index              
                if (_index(draging) < _index(target)) {
                    target.parentNode.insertBefore(draging, target.nextSibling);
                } else {
                    target.parentNode.insertBefore(draging, target);
                }
        }
    }

接下去就是活动正在拖动的li了,当前li的index大于容器li时就插入在容器的前头,反之插入在容器的末尾,那么怎么获取当前li的index呢?Node有三个天性previousElementSibling,表示该因素前边的一个要素,那么我们可以这么

function _index(el) {
        var index = 0;
        if (!el || !el.parentNode) {
            return -1;
        }
        while (el && (el = el.previousElementSibling)) {
            index++;
        }
        return index;
    }

好的,基本的排序就搞好了,在线演示地址http://jsrun.net/GkiKp/edit

复制代码 代码如下:

复制代码 代码如下:

复制代码 代码如下:

动画

好了,先讲思路,动画其实没有必要给全体因素都助长,只要求给移动的成分和对象成分增添动画就够了,比如我们调换了1和2的职位,那么就给1和2加多动画。这种拉长动画的笔触是通用的,例如能够做成分的页面步向动画。

图片 6

1和2

我们能够记录1和2沟通事先的职责,然后拿走沟通之后的职分,然后让要素从原来的地方置慢慢移动到目的地方。
图形表示

图片 7

图片表示

那正是说我们先拿走初步地点,料定是在活动成分从前进行获取,那么我们在dragover移动成分在此以前拉长

var targetRect = target.getBoundingClientRect();
var dragingRect = draging.getBoundingClientRect();

然后在沟通地点然后再也猎取成分地方

var targetAfter = target.getBoundingClientRect();
var dragingAfter = draging.getBoundingClientRect();

<span style=”font-size:14px”><!DOCTYPE html PUBLIC “-//W3C//DTD
XHTML 1.0 Transitional//EN”
“;
<html xmlns=”;
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″
/>
<title>Demo</title>
</head>

<span style=”font-size:14px”><!DOCTYPE html PUBLIC “-//W3C//DTD
XHTML 1.0 Transitional//EN”
“;
<html xmlns=”;
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″
/>
<title>Demo</title>
</head>

Drag.init({
handler: document.getElementById(“handler”),
root:document.getElementById(“root”);
});
<div id=”root”>
<h2 id=”handler”></h2>
</div>

岗位还原

先获得两岸的差,然后就足感觉其增添transform,由于大家需求将成分弹指间运动到原本的职分,所以大家必要将其transition设为none

target.style.transition='none';
target.style.transform='translate3d(' +
                (targetRect.left - targetAfter.left) + 'px,' +
                (targetRect.top - targetAfter.top) + 'px,0)'

//draging同理

然后就足以再设置transform进行移动,这里如若直接设置的话,当然动画是无可奈何浮现的,原因能够看这里

target.offsetWidth; //触发重绘
target.style.transition='all 300ms';
target.style.transform='translate3d(0,0,0)';

<body style=”width:2000px; height:1000px;”>
<div id=”demo” style=”position:absolute; left:518px; right:100px;
width:500px; height:500px; background:#CC0000; top:
114px;”>德姆o为了方便就一向用相对定位的因素</div>
</body>
</html>
<script>
document.getElementById(‘demo’).onclick=function (){
if (document.documentElement.getBoundingClientRect) {
alert(“left:”+this.getBoundingClientRect().left)
alert(“top:”+this.getBoundingClientRect().top)
alert(“right:”+this.getBoundingClientRect().right)
alert(“bottom:”+this.getBoundingClientRect().bottom)
<strong>var X=
this.getBoundingClientRect().left+document.documentElement.scrollLeft;
var Y =
this.getBoundingClientRect().top+document.documentElement.scrollTop;</strong>
alert(“德姆o的地方是X:”+X+”;Y:”+Y)
}
}
</script></span>

<body style=”width:2000px; height:1000px;”>
<div id=”demo” style=”position:absolute; left:518px; right:100px;
width:500px; height:500px; background:#CC0000; top:
114px;”>德姆o为了方便就径直用相对定位的要素</div>
</body>
</html>
<script>
document.getElementById(‘demo’).onclick=function (){
if (document.documentElement.getBoundingClientRect) {
alert(“left:”+this.getBoundingClientRect().left)
alert(“top:”+this.getBoundingClientRect().top)
alert(“right:”+this.getBoundingClientRect().right)
alert(“bottom:”+this.getBoundingClientRect().bottom)
<strong>var X=
this.getBoundingClientRect().left+document.documentElement.scrollLeft;
var Y =
this.getBoundingClientRect().top+document.documentElement.scrollTop;</strong>
alert(“德姆o的职位是X:”+X+”;Y:”+Y)
}
}
</script></span>

2、在onmousemove事件中来拍卖被拖移成分的地方的变通,其实轻巧成分要运动的离开便是…

还恐怕有三个主题材料

鉴于大家的卡通是增多在dragover里面,但是dragover是会不停的接触,加过正是因素不停“抽搐”,所以我们须求看清成分是或不是已经增添了动画片。这么些的话方法就那么些了,这里作者是设置了贰个电火花计时器,事件到了今后将transition和transform清空,设置动画之前开展剖断沙漏是或不是早就存在

clearTimeout(target.animated);
target.animated = setTimeout(function() {
target.style.transition='';
target.style.transform='';
target.animated = false;
//draging同理
}, ms);

) 来收获页面成分的职位
复制代码 代码如下: document.documentElement.getBoundingClientRect
该办法再次来到多少个目的,进而获得页面中某…

你大概感兴趣的稿子:

  • JS达成可缩放、拖动、关闭和最小化的变通窗口完整实例
  • js用拖动滑块来调整图片大小的不二等秘书技
  • Js可拖拽放大的层拖动特效完结格局
  • JS+CSS完毕可拖动的弹出提醒框
  • js达成图片拖动改动各样附图
  • js完成可拖动DIV的艺术
  • 原生JS可拖动掸窗效果实例代码
  • 通过遮罩层完结浮层DIV登入的js代码
  • JS达成动态移动层及拖动浮层关闭的主意

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图