JavaScript事件模拟元素拖动
来源:互联网 发布:淘宝 三文鱼 编辑:程序博客网 时间:2024/05/23 16:41
一、前言:
最近要实现一个元素拖放效果,鼠标拖动元素并且定位元素,首先想到的是HTML5中的拖放,在HTML5中,有一个draggable属性,且有dragstart, dragover, drop等事件,主要是通过event.dataTransfer对象方法,在dragstart事件中设置数据event.dataTransfer.setData(); 在drop事件中获取数据event.dataTransfer.getData();但是它并不能实现元素的实时拖放效果,因此还是需要用鼠标事件来模拟元素的拖放。
二、实例示图
三、实现原理:
1、思路:鼠标依次触发mousedown, mousemove, mouseup事件,在mousemove事件中实时计算元素新位置并且定位元素,
在mouseup事件中注销mousemove,mouseup事件。
2、重点:如果所有事件都绑定在拖动元素上,当鼠标移动速度很快,以至于离开了拖动的元素,那么就不会执行mousemove,
mouseup事件处理程序,因此要想让mousemove,mouseup事件处理实时执行,必须将它们绑定到document元素上;
四、插件源码:
$.fn.extend({ /** * * 扩展jQuery原型,实现鼠标事件模拟元素拖动 * drag中的回调函数this指向被拖动元素 * @ method: drag * @ use: $( selector ).drag( dragStart, dragMove, dragEnd ) * @ param { function } 第一个参数,准备拖动处理函数 * @ param { function } 第二个参数,拖动中处理函数 * @ param { function } 第三个参数,拖动结束处理函数 * @ reutrn { jQuery( selector ) } * */ drag: function( dragStart, dragMove, dragEnd ) { function drag( dragElem, event ) { var offsetX, offsetY, beforePageX, beforePageY; if ( $.isFunction(dragStart) ) { dragStart.apply(dragElem, arguments); } // 移动前或移动中的元素位置 offsetX = parseInt( $(dragElem).css('left'), 10 ); offsetY = parseInt( $(dragElem).css('top'), 10 ); // 移动前或移动中的鼠标位置 beforePageX = event.clientX; beforePageY = event.clientY; if ( document.addEventListener ) { document.addEventListener('mousemove', moveHandle, false); document.addEventListener('mouseup', upHandle, false); } else if ( document.attachEvent ) { dragElem.setCapture(); // 将dragElem鼠标事件继承到文档进行捕获 dragElem.attachEvent('onmousemove', moveHandle); dragElem.attachEvent('onmouseup', upHandle); dragElem.attachEvent('onlosecapture', upHandle); } // 鼠标移动事件处理 function moveHandle (event) { var event = event || window.event; // 更新移动中或移动终止后的元素位置 var x = offsetX + event.clientX - beforePageX; var y = offsetY + event.clientY - beforePageY; $(dragElem).css({ left: x + 'px', top: y + 'px' }); // 阻止事件传播 if ( event.stopPropagation ){ event.stopPropagation(); } else if ( event.cancleBubble ) { event.cancleBubble = true; } if ( $.isFunction(dragMove) ) { dragMove.apply(dragElem, arguments); } } // 鼠标弹起事件处理 function upHandle (event) { if ( document.addEventListener ) { document.removeEventListener('mousemove', moveHandle, false); document.removeEventListener('mouseup', upHandle, false); } else if ( document.detachEvent ) { dragElem.detachEvent('onlosecapture', upHandle); dragElem.detachEvent('onmouseup', upHandle); dragElem.detachEvent('onmousemove', moveHandle); dragElem.releaseCapture(); } if ( event.stopPropagation ){ event.stopPropagation(); } else if ( event.cancleBubble ) { event.cancleBubble = true; } if ( $.isFunction(dragEnd) ) { dragEnd.apply(dragElem, arguments); } } } $(this).each(function(){ $(this).bind('mousedown', function(e){ var dragElem = this, event = e; drag(dragElem, event); }); }); return this; }});
五、调用实例:
(function(){ var dragEnd = false; $('.drag-elem').drag( function(){ $(this).text('准备拖动').css({ zIndex: 2 }).siblings().css({ zIndex: 1 }); }, function(){ var offset = $(this).offset(); dragEnd = true; $(this).text('拖动中(' + offset.left + ',' + offset.top + ')' ); }, function(){ if (dragEnd) { $(this).text('拖动结束'); dragEnd = false; } } );}());
六、完整实例代码
<!doctype html><html><head><meta charset="utf-8"><title>jQuery drag</title><script src="http://code.jquery.com/jquery-1.10.1.js"></script><style>.drag-elem { position: absolute; left: 10px; top: 20px; z-index: 999; width: 200px; height: 50px; cursor: move; background-color: #ccc; border: 5px solid green; font-size: 24px; line-height: 50px; text-align: center; }</style></head><body><div class="drag-elem"></div><script>$.fn.extend({ /** * * 扩展jQuery原型,实现鼠标事件模拟元素拖动 * drag中的回调函数this指向被拖动元素 * @ method: drag * @ use: $( selector ).drag( dragStart, dragMove, dragEnd ) * @ param { function } 第一个参数,准备拖动处理函数 * @ param { function } 第二个参数,拖动中处理函数 * @ param { function } 第三个参数,拖动结束处理函数 * @ reutrn { jQuery( selector ) } * */ drag: function( dragStart, dragMove, dragEnd ) { function drag( dragElem, event ) { var offsetX, offsetY, beforePageX, beforePageY; if ( $.isFunction(dragStart) ) { dragStart.apply(dragElem, arguments); } // 移动前或移动中的元素位置 offsetX = parseInt( $(dragElem).css('left'), 10 ); offsetY = parseInt( $(dragElem).css('top'), 10 ); // 移动前或移动中的鼠标位置 beforePageX = event.clientX; beforePageY = event.clientY; if ( document.addEventListener ) { document.addEventListener('mousemove', moveHandle, false); document.addEventListener('mouseup', upHandle, false); } else if ( document.attachEvent ) { dragElem.setCapture(); // 将dragElem鼠标事件继承到文档进行捕获 dragElem.attachEvent('onmousemove', moveHandle); dragElem.attachEvent('onmouseup', upHandle); dragElem.attachEvent('onlosecapture', upHandle); } // 鼠标移动事件处理 function moveHandle (event) { var event = event || window.event; // 更新移动中或移动终止后的元素位置 var x = offsetX + event.clientX - beforePageX; var y = offsetY + event.clientY - beforePageY; $(dragElem).css({ left: x + 'px', top: y + 'px' }); // 阻止事件传播 if ( event.stopPropagation ){ event.stopPropagation(); } else if ( event.cancleBubble ) { event.cancleBubble = true; } if ( $.isFunction(dragMove) ) { dragMove.apply(dragElem, arguments); } } // 鼠标弹起事件处理 function upHandle (event) { if ( document.addEventListener ) { document.removeEventListener('mousemove', moveHandle, false); document.removeEventListener('mouseup', upHandle, false); } else if ( document.detachEvent ) { dragElem.detachEvent('onlosecapture', upHandle); dragElem.detachEvent('onmouseup', upHandle); dragElem.detachEvent('onmousemove', moveHandle); dragElem.releaseCapture(); } if ( event.stopPropagation ){ event.stopPropagation(); } else if ( event.cancleBubble ) { event.cancleBubble = true; } if ( $.isFunction(dragEnd) ) { dragEnd.apply(dragElem, arguments); } } } $(this).each(function(){ $(this).bind('mousedown', function(e){ var dragElem = this, event = e; drag(dragElem, event); }); }); return this; }});</script><script>(function(){ var dragEnd = false; $('.drag-elem').drag( function(){ $(this).text('准备拖动').css({ zIndex: 2 }).siblings().css({ zIndex: 1 }); }, function(){ var offset = $(this).offset(); dragEnd = true; $(this).text('拖动中(' + offset.left + ',' + offset.top + ')' ); }, function(){ if (dragEnd) { $(this).text('拖动结束'); dragEnd = false; } } );}());</script></body></html>
源码更新 2014/02/19
$.fn.extend({ /** * * 扩展jQuery原型,实现鼠标事件模拟元素拖动 * drag中的回调函数this指向被拖动元素 * @ method: drag * @ use: $( selector ).drag( dragStartFn, dragMoveFn, dragEndFn ) * @ param { function } 第一个参数,准备拖动处理函数 * @ param { function } 第二个参数,拖动中处理函数 * @ param { function } 第三个参数,拖动结束处理函数 * @ reutrn { jQuery( selector ) } * */ drag: function( dragStartFn, dragMoveFn, dragEndFn ) { function drag( target, e ) { var offsetX, offsetY, beforePageX, beforePageY; if ( $.isFunction(dragStartFn) ) { dragStartFn.apply(target, arguments); } // 移动前或移动中的元素位置 offsetX = parseInt( $(target).css('left'), 10 ) || 0; offsetY = parseInt( $(target).css('top'), 10 ) || 0; // 移动前或移动中的鼠标位置 beforePageX = e.clientX; beforePageY = e.clientY; $(document).bind('mousemove', moveHandle) .bind('mouseup', upHandle); // 鼠标移动事件处理 function moveHandle (e) { // 更新移动中或移动终止后的元素位置 var x = offsetX + e.clientX - beforePageX; var y = offsetY + e.clientY - beforePageY; $(target).css({ left: x + 'px', top: y + 'px' }); if ( $.isFunction(dragMoveFn) ) { dragMoveFn.apply(target, arguments); } // 阻止浏览器默认行为(鼠标在拖动图片一小段距离,会出现一个禁止的小提示,即:图片不能再拖动) e.preventDefault(); } // 鼠标弹起事件处理 function upHandle (e) { $(document).unbind('mousemove', moveHandle) .unbind('mouseup', upHandle); if ( $.isFunction(dragEndFn) ) { dragEndFn.apply(target, arguments); } } } $(this).each(function(){ $(this).bind('mousedown', function(e){ drag(this, e); }); }); return this; }});// 调用实例(function(){ var dragEnd = false; $('div').drag( function(){ $(this).html('<span>准备拖动</span>').css({ zIndex: 2 }).siblings().css({ zIndex: 1 }); }, function(){ var offset = $(this).offset(); $(this).html('<span>拖动中(' + offset.left + ',' + offset.top + ')</span>' ); }, function(){ $(this).html('<span>拖动结束</span>') } ); $('img').drag();}());
0 0
- JavaScript事件模拟元素拖动
- JavaScript:拖动事件
- 原生javascript实现拖动元素
- JavaScript事件来源元素
- Javascript事件模拟
- JavaScript 模拟事件触发
- Javascript事件模拟
- 浅谈Javascript事件模拟
- JavaScript模拟鼠标事件
- javascript模拟原生事件
- JavaScript:模拟事件
- javascript 实现元素拖动的源代码
- Javascript事件对象+鼠标拖动实例
- Javascript事件模拟(鼠标事件、键盘事件)
- Javascript处理DOM元素事件
- JavaScript模拟用户单击事件
- JavaScript模拟用户单击事件
- JavaScript模拟用户单击事件
- 博客之旅
- rigidbody中Is Kinematic选中后不受force影响
- 线索二叉树
- AngularJs事件大集合
- [BZOJ4775][点分树][概率与期望][数学][卡精度]网管
- JavaScript事件模拟元素拖动
- ubuntu 16.04下搜狗输入法不能输入中文解决
- 全排列算法(递归)
- 10分钟学会Markdown常用语法在markdown编辑器中的显示效果
- java基础
- python进行中文文本聚类实例(TFIDF计算、词袋构建)
- 猜数字小游戏
- Servlet二
- java之session--获取最近浏览商品(获取cookie值)算法思想及代码