时间:2021-05-26
这篇文章详细介绍了JS拖拽插件的实现步骤,主要从以下六步做详细分析,具体内容如下:
一、js拖拽插件的原理
二、根据原理实现的最基本效果
三、代码抽象与优化
四、扩展:有效的拖拽元素
五、性能优化和总结
六、jquery插件化
js拖拽是常见的网页效果,本文将从零开始实现一个简单的js插件。
一、js拖拽插件的原理
常见的拖拽操作是什么样的呢?整过过程大概有下面几个步骤:
1、用鼠标点击被拖拽的元素
2、按住鼠标不放,移动鼠标
3、拖拽元素到一定位置,放开鼠标
这里的过程涉及到三个dom事件:onmousedown,onmousemove,onmouseup。所以拖拽的基本思路就是:
1、用鼠标点击被拖拽的元素触发onmousedown
(1)设置当前元素的可拖拽为true,表示可以拖拽
(2)记录当前鼠标的坐标x,y
(3)记录当前元素的坐标x,y
2、移动鼠标触发onmousemove
(1)判断元素是否可拖拽,如果是则进入步骤2,否则直接返回
(2)如果元素可拖拽,则设置元素的坐标
元素的x坐标 = 鼠标移动的横向距离+元素本来的x坐标 = 鼠标现在的x坐标 - 鼠标之前的x坐标 + 元素本来的x坐标
元素的y坐标 = 鼠标移动的横向距离+元素本来的y坐标 = 鼠标现在的y坐标 - 鼠标之前的y坐标 + 元素本来的y坐标
3、放开鼠标触发onmouseup
(1)将鼠标的可拖拽状态设置成false
回到顶部
二、根据原理实现的最基本效果
在实现基本的效果之前,有几点需要说明的:
1、元素想要被拖动,它的postion属性一定要是relative或absolute
2、通过event.clientX和event.clientY获取鼠标的坐标
3、onmousemove是绑定在document元素上而不是拖拽元素本身,这样能解决快速拖动造成的延迟或停止移动的问题
代码如下:
复制代码 代码如下:
; (function (window, undefined) {
function Drag(ele) {}
window.Drag = Drag;
})(window, undefined);
用自执行匿名函数将代码包起来,内部定义Drag方法并暴露到全局中,直接调用Drag,传入被拖拽的元素。
首先对一些常用的方法进行简单的封装:
在一个拖拽操作中,存在着两个对象:被拖拽的对象和鼠标对象,我们定义了下面的两个对象以及它们对应的操作:
首先的拖拽对象,它包含一个元素节点和拖拽之前的坐标x和y:
还有一个对象是鼠标,它主要包含x坐标和y坐标:
function Mouse() { this.x = ; this.y = ; } Mouse.prototype.setXY = function (x, y) { this.x = parseInt(x); this.y = parseInt(y); }这是在拖拽操作中定义的两个对象。
如果一个页面可以有多个拖拽元素,那应该注意什么:
1、每个元素对应一个拖拽对象实例
2、每个页面只能有一个正在拖拽中的元素
为此,我们定义了唯一一个对象用来保存相关的配置:
复制代码 代码如下:
var draggableConfig = {
zIndex: ,
draggingObj: null,
mouse: new Mouse()
};
这个对象中有三个属性:
(1)zIndex:用来赋值给拖拽对象的zIndex属性,有多个拖拽对象时,当两个拖拽对象重叠时,会造成当前拖拽对象有可能被挡住,通过设置zIndex使其显示在最顶层
(2)draggingObj:用来保存正在拖拽的对象,在这里去掉了前面的用来判断是否可拖拽的变量,通过draggingObj来判断当前是否可以拖拽以及获取相应的拖拽对象
(3)mouse:唯一的鼠标对象,用来保存当前鼠标的坐标等信息
最后是绑定onmousedown,onmouseover,onmouseout事件,整合上面的代码如下:
; (function (window, undefined) { var dom = { //绑定事件 on: function (node, eventName, handler) { if (node.addEventListener) { node.addEventListener(eventName, handler); } else { node.attachEvent("on" + eventName, handler); } }, //获取元素的样式 getStyle: function (node, styleName) { var realStyle = null; if (window.getComputedStyle) { realStyle = window.getComputedStyle(node, null)[styleName]; } else if (node.currentStyle) { realStyle = node.currentStyle[styleName]; } return realStyle; }, //获取设置元素的样式 setCss: function (node, css) { for (var key in css) { node.style[key] = css[key]; } } }; //#region 拖拽元素类 function DragElement(node) { this.node = node; this.x = ; this.y = ; } DragElement.prototype = { constructor: DragElement, init: function () { this.setEleCss({ "left": dom.getStyle(node, "left"), "top": dom.getStyle(node, "top") }) .setXY(node.style.left, node.style.top); }, setXY: function (x, y) { this.x = parseInt(x) || ; this.y = parseInt(y) || ; return this; }, setEleCss: function (css) { dom.setCss(this.node, css); return this; } } //#endregion //#region 鼠标元素 function Mouse() { this.x = ; this.y = ; } Mouse.prototype.setXY = function (x, y) { this.x = parseInt(x); this.y = parseInt(y); } //#endregion //拖拽配置 var draggableConfig = { zIndex: , draggingObj: null, mouse: new Mouse() }; function Drag(ele) { this.ele = ele; function mouseDown(event) { var ele = event.target || event.srcElement; draggableConfig.mouse.setXY(event.clientX, event.clientY); draggableConfig.draggingObj = new DragElement(ele); draggableConfig.draggingObj .setXY(ele.style.left, ele.style.top) .setEleCss({ "zIndex": draggableConfig.zIndex++, "position": "relative" }); } ele.onselectstart = function () { //防止拖拽对象内的文字被选中 return false; } dom.on(ele, "mousedown", mouseDown); } dom.on(document, "mousemove", function (event) { if (draggableConfig.draggingObj) { var mouse = draggableConfig.mouse, draggingObj = draggableConfig.draggingObj; draggingObj.setEleCss({ "left": parseInt(event.clientX - mouse.x + draggingObj.x) + "px", "top": parseInt(event.clientY - mouse.y + draggingObj.y) + "px" }); } }) dom.on(document, "mouseup", function (event) { draggableConfig.draggingObj = null; }) window.Drag = Drag; })(window, undefined);调用方法:Drag(document.getElementById("obj"));
注意的一点,为了防止选中拖拽元素中的文字,通过onselectstart事件处理程序return false来处理这个问题。
四、扩展:有效的拖拽元素
我们常见的一些拖拽效果很有可能是这样的:
弹框的顶部是可以进行拖拽操作的,内容区域是不可拖拽的,怎么实现这样的效果呢:
首先优化拖拽元素对象如下,增加一个目标元素target,表示被拖拽对象,在上图的登录框中,就是整个登录窗口。
被记录和设置坐标的拖拽元素就是这个目标元素,但是它并不是整个部分都是拖拽的有效部分。我们在html结构中为拖拽的有效区域添加类draggable表示有效拖拽区域:
复制代码 代码如下:
<div id="obj" class="dialog" style="position:relative;left:px">
<div class="header draggable">
拖拽的有效元素
</div>
<div class="content">
拖拽对象
</div>
</div>
然后修改Drag方法如下:
主要修改的是绑定mousedown的节点变成了包含draggable类的有效元素,如果不含有draggable,则整个元素都是有效元素。
五、性能优化和总结
由于onmousemove在一直调用,会造成一些性能问题,我们可以通过setTimout来延迟绑定onmousemove事件,改进move函数如下
总结:
整个拖拽插件的实现其实很简单,主要是要注意几点
1、实现思路:元素拖拽位置的改变就等于鼠标改变的距离,关键在于获取鼠标的变动和元素原本的坐标
2、通过setTimeout来延迟加载onmousemove事件来提供性能
六、jquery插件化
简单地将其封装成jquery插件,主要是相关的dom方法替换成jquery方法来操作
以上就是本文对JS拖拽插件实现步骤的详细介绍,希望对大家有所帮助。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
针对android系统不支持pdf文档在线预览,可通过引入pdf.js插件实现,其具体实现步骤如下一、引入插件方式一:npminstall--savepdfjs
JS实现图片拖拽交换效果,供大家参考,具体内容如下听WEB前端javascript企业实战班公开课,用JS实现了图片拖拽交换的目的;感谢老师的讲解。实现要点鼠标
本文实例讲述了JS弹出可拖拽可关闭的div层完整实现方法。分享给大家供大家参考。具体实现方法如下:复制代码代码如下:JS弹出可拖拽可关闭的div层html,bo
使用jquery拖拽排序插件制作拖拽排序效果是一款非常实用的鼠标拖拽布局插件。效果图如下:效果演示源码下载html代码:水平拖拽12345$(function(
本文实例为大家分享了js面向对象方式实现拖拽的具体代码,供大家参考,具体内容如下拖拽功能的实现原理:(直接拿走!)Document#box{position:a