js 可拖动列表实现代码


Posted in Javascript onDecember 13, 2011

补充一点:
要禁止移动中选中文字,FF可以设置CSS
xxxx{-moz-user-select:none;}
其他的浏览器可以设置
XXXX.onselectstart = function(){return false}
一种实现原理就是点击没目标元素之后,创建一个占位元素(或者复制一份目标元素,即拷贝B),然后拖动目标元素(或者复制的来的新元素B);
找到相应的位置之后,插入目标元素。清除占位元素或者B。
比如有一个列表:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
<title></title> 
<style type="text/css"> 
*{ margin: 0; padding: 0; -moz-user-select:none;} 
ul{ margin: 100px; border: 1px solid #adff2f; list-style: none;} 
li{ height: 30px; line-height: 30px; padding: 0; list-style: none;} 
li:hover{ background: #bdb76b; cursor: move;} 
</style> 
</head> 
<body> 
<ul id="outer_wrap"> 
<li>第一条</li> 
<li>第二条</li> 
<li>第三条</li> 
<li>第四条</li> 
<li>第五条</li> 
<li>第六条</li> 
<li>第七条</li> 
<li>第八条</li> 
</ul> 
</body> 
</html>

点击“<li>第一条</li>”(记为元素A),获取““<li>第一条</li>””的位置和尺寸信息,把元素A拷贝一遍(记为元素B),然后插入文档中,将元素B绝对定位到元素A的位置,然后鼠标移动的时候,元素B跟着拖动,接着就是判断插入点。
判断插入点就是判断当前鼠标所在的坐标,如果鼠标坐标落在除了元素A之外的其他LI元素范围之内,就满足可插入的条件,同时上半部分就插入到前面,下半部分就插入到后面。(=。= 个人口味重,觉得这段话好邪恶啊)

js 可拖动列表实现代码
为了标示出插入的位置,我们在选中的插入点处另插入一个元素,仅作标杆用。
下面是一个demo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
<title></title> 
<style type="text/css"> 
*{ margin: 0; padding: 0; -moz-user-select:none;} 
ul{ margin: 100px; border: 1px solid #adff2f; list-style: none;} 
li{ height: 30px; line-height: 30px; padding: 0; list-style: none;} 
li:hover{ background: #bdb76b; cursor: move;} 
</style> 
</head> 
<body> 
<ul id="outer_wrap"> 
<li>第一条</li> 
<li>第二条</li> 
<li>第三条</li> 
<li>第四条</li> 
<li>第五条</li> 
<li>第六条</li> 
<li>第七条</li> 
<li>第八条</li> 
</ul> 
<script type="text/javascript"> 
function $(id){ 
return document.getElementById(id); 
} 
//获取鼠标位置 
function getMousePos(e){ 
return { 
x : e.pageX || e.clientX + document.body.scrollLeft, 
y : e.pageY || e.clientY + document.body.scrollTop 
} 
} 
//获取元素位置 
function getElementPos(el){ 
return { 
x : el.offsetParent ? el.offsetLeft + arguments.callee(el.offsetParent)['x'] : el.offsetLeft, 
y : el.offsetParent ? el.offsetTop + arguments.callee(el.offsetParent)['y'] : el.offsetTop 
} 
} 
//获取元素尺寸 
function getElementSize(el){ 
return { 
width : el.offsetWidth, 
height : el.offsetHeight 
} 
} 
//禁止选择 
document.onselectstart = function(){ 
return false; 
} 
//判断是否有挪动 
var MOVE = {}; 
MOVE.isMove = false; //就是创建的标杆 
var div = document.createElement('div'); 
div.style.width = '400px'; 
div.style.height = '1px'; 
div.style.fontSize = '0'; 
div.style.background = 'red'; 
var outer_wrap = $('outer_wrap'); 
outer_wrap.onmousedown = function(event){ 
//获取列表顺序 
var lis = outer_wrap.getElementsByTagName('li'); 
for(var i = 0; i < lis.length; i++){ 
lis[i]['pos'] = getElementPos(lis[i]); 
lis[i]['size'] = getElementSize(lis[i]); 
} 
event = event || window.event; 
var t = event.target || event.srcElement; 
if(t.tagName.toLowerCase() == 'li'){ 
var p = getMousePos(event); 
var el = t.cloneNode(true); 
el.style.position = 'absolute'; 
el.style.left = t.pos.x + 'px'; 
el.style.top = t.pos.y + 'px'; 
el.style.width = t.size.width + 'px'; 
el.style.height = t.size.height + 'px'; 
el.style.border = '1px solid #d4d4d4'; 
el.style.background = '#d4d4d4'; 
el.style.opacity = '0.7'; 
document.body.appendChild(el); 
document.onmousemove = function(event){ 
event = event || window.event; 
var current = getMousePos(event); 
el.style.left =t.pos.x + current.x - p.x + 'px'; 
el.style.top =t.pos.y + current.y - p.y+ 'px'; 
document.body.style.cursor = 'move'; 
//判断插入点 
for(var i = 0; i < lis.length; i++){ 
if(current.x > lis[i]['pos']['x'] && current.x < lis[i]['pos']['x'] + lis[i]['size']['width'] && current.y > lis[i]['pos']['y'] && current.y < lis[i]['pos']['y'] + lis[i]['size']['height']/2){ 
if(t != lis[i]){ 
MOVE.isMove = true; 
outer_wrap.insertBefore(div,lis[i]); 
} 
}else if(current.x > lis[i]['pos']['x'] && current.x < lis[i]['pos']['x'] + lis[i]['size']['width'] && current.y > lis[i]['pos']['y'] + lis[i]['size']['height']/2 && current.y < lis[i]['pos']['y'] + lis[i]['size']['height']){ 
if(t != lis[i]){ 
MOVE.isMove = true; 
outer_wrap.insertBefore(div,lis[i].nextSibling); 
} 
} 
} 
} 
//移除事件 
document.onmouseup = function(event){ 
event = event || window.event; 
document.onmousemove = null; 
if(MOVE.isMove){ 
outer_wrap.replaceChild(t,div); 
MOVE.isMove = false; 
} 
document.body.removeChild(el); 
el = null; 
document.body.style.cursor = 'normal'; 
document.onmouseup = null; 
} 
} 
} 
</script> 
</body> 
</html>

上面的demo代码细节欠缺考虑,仅供展示原理。
Javascript 相关文章推荐
HTML页面如何象ASP一样接受参数
Feb 07 Javascript
基于jQuery的合并表格中相同文本的相邻单元格的代码
Apr 06 Javascript
Tab页界面 用jQuery及Ajax技术实现(php后台)
Oct 12 Javascript
JavaScript阻止浏览器返回按钮的方法
Mar 18 Javascript
Bootstrap CSS组件之输入框组
Dec 17 Javascript
js评分组件使用详解
Jun 06 Javascript
ajax请求data遇到的问题分析
Jan 18 Javascript
JS实现的视频弹幕效果示例
Aug 17 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
Sep 20 Javascript
借助云开发实现小程序短信验证码的发送
Jan 06 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
Mar 17 Javascript
Openlayers显示瓦片网格信息的方法
Sep 28 Javascript
使用Mootools动态添加Css样式表代码,兼容各浏览器
Dec 12 #Javascript
分享一个用Mootools写的鼠标滑过进度条改变进度值的实现代码
Dec 12 #Javascript
背景图跟随鼠标移动的Mootools插件实现代码
Dec 12 #Javascript
用Mootools获得操作索引的两种方法分享
Dec 12 #Javascript
整理8个很棒的 jQuery 倒计时插件和教程
Dec 12 #Javascript
关于event.cancelBubble和event.stopPropagation()的区别介绍
Dec 11 #Javascript
Jquery阻止事件冒泡 event.stopPropagation
Dec 11 #Javascript
You might like
乐信RP2100的电路分析和打磨
2021/03/02 无线电
可以在线执行PHP代码包装修正版
2008/03/15 PHP
PHP将二维数组某一个字段相同的数组合并起来的方法
2016/02/26 PHP
浅析php如何实现爬取数据原理
2018/09/27 PHP
jquery.validate使用攻略 第一部
2010/07/01 Javascript
javascript模版引擎-tmpl的bug修复与性能优化分析
2011/10/23 Javascript
向当前style sheet中插入一个新的style实现方法
2013/04/01 Javascript
js判断上传文件的类型和大小示例代码
2013/10/18 Javascript
表单元素与非表单元素刷新区别详细解析
2013/11/06 Javascript
js调出上下文菜单的实例
2015/12/17 Javascript
WebGL利用FBO完成立方体贴图效果完整实例(附demo源码下载)
2016/01/26 Javascript
JavaScript操作HTML DOM节点的基础教程
2016/03/11 Javascript
Javascript实现通过选择周数显示开始日和结束日的实现代码
2016/05/30 Javascript
如何解决手机浏览器页面点击不跳转浏览器双击放大网页
2016/07/01 Javascript
第一次接触神奇的Bootstrap导航条
2016/08/09 Javascript
微信小程序 绘图之饼图实现
2016/10/24 Javascript
JavaScript中最常见的三个面试题解析
2017/03/04 Javascript
JS实现基于Sketch.js模拟成群游动的蝌蚪运动动画效果【附demo源码下载】
2017/08/18 Javascript
jQuery点击页面其他部分隐藏下拉菜单功能
2018/11/27 jQuery
在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟
2018/11/28 Javascript
记录一次开发微信网页分享的步骤
2019/05/07 Javascript
Vue+Vuex实现自动登录的知识点详解
2020/03/04 Javascript
利用React高阶组件实现一个面包屑导航的示例
2020/08/23 Javascript
Python 加密的实例详解
2017/10/09 Python
Python实现判断字符串中包含某个字符的判断函数示例
2018/01/08 Python
Python读写zip压缩文件的方法
2018/08/29 Python
Python中logging.NullHandler 的使用教程
2018/11/29 Python
python把转列表为集合的方法
2019/06/28 Python
Django Admin设置应用程序及模型顺序方法详解
2020/04/01 Python
详解Python 函数参数的拆解
2020/09/02 Python
详解用python -m http.server搭一个简易的本地局域网
2020/09/24 Python
俄罗斯小米家用电器、电子产品和智能家居商店:Poood.ru
2020/04/03 全球购物
消防安全管理制度
2014/02/01 职场文书
四年级评语大全
2014/04/21 职场文书
演讲开场白和结束语
2015/05/29 职场文书
2015年幼儿园国庆节活动总结
2015/07/30 职场文书