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 相关文章推荐
JavaScript中的分号插入机制详细介绍
Feb 11 Javascript
jQuery.position()方法获取不到值的安全替换方法
Mar 13 Javascript
jquery实现Ctrl+Enter提交表单的方法
Jul 21 Javascript
JavaScript各类型的关系图解
Oct 16 Javascript
浅析JavaScript访问对象属性和方法及区别
Nov 16 Javascript
jQuery旋转木马式幻灯片轮播特效
Dec 04 Javascript
用angular实现多选按钮的全选与反选实例代码
May 23 Javascript
react+redux的升级版todoList的实现
Dec 18 Javascript
JS中Map和ForEach的区别
Feb 05 Javascript
webpack4.x打包过程详解
Jul 18 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
Oct 08 Javascript
Angular6 发送手机验证码按钮倒计时效果实现方法
Jan 08 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
默默简单的写了一个模板引擎
2007/01/02 PHP
php数组函数序列之array_key_exists() - 查找数组键名是否存在
2011/10/29 PHP
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
2013/04/08 PHP
PHP统计二维数组元素个数的方法
2013/11/12 PHP
PHP使用curl模拟post上传及接收文件的方法
2016/03/04 PHP
php实现生成验证码实例分享
2016/04/10 PHP
php中array_unshift()修改数组key注意事项分析
2016/05/16 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
浅谈PHP中的Trait使用方法
2019/03/22 PHP
jQuery实战之仿淘宝商城左侧导航效果
2011/04/12 Javascript
最常用的12种设计模式小结
2011/08/09 Javascript
如何将JS的变量值传递给ASP变量
2012/12/10 Javascript
JQuery操作tr和td内容的方法实例
2013/03/06 Javascript
html的DOM中document对象images集合用法实例
2015/01/21 Javascript
JQuery validate插件验证用户注册信息
2016/05/11 Javascript
JavaScript生成带有缩进的表格代码
2016/06/15 Javascript
AngularJS  双向数据绑定详解简单实例
2016/10/20 Javascript
Vue.js组件tab实现选项卡切换
2020/03/23 Javascript
详解微信小程序设置底部导航栏目方法
2017/06/29 Javascript
vue2.0 使用element-ui里的upload组件实现图片预览效果方法
2018/09/04 Javascript
webpack打包非模块化js的方法
2018/10/24 Javascript
JS中的一些常用的函数式编程术语
2019/06/15 Javascript
javascript中正则表达式语法详解
2020/08/07 Javascript
react实现复选框全选和反选组件效果
2020/08/25 Javascript
用Python编写脚本使IE实现代理上网的教程
2015/04/23 Python
python字典的常用操作方法小结
2016/05/16 Python
Python3网络爬虫中的requests高级用法详解
2019/06/18 Python
python 画3维轨迹图并进行比较的实例
2019/12/06 Python
html5实现canvas阴影效果示例
2014/05/07 HTML / CSS
HTML5新增加的功能详解
2016/09/05 HTML / CSS
汽车专业人才自我鉴定范文
2013/12/29 职场文书
2015年师德表现自我评价
2015/03/05 职场文书
2015年审计人员工作总结
2015/05/26 职场文书
骆驼祥子读书笔记
2015/06/26 职场文书
python实现简易自习室座位预约系统
2021/06/30 Python
pandas中关于apply+lambda的应用
2022/02/28 Python