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实现划词标记+划词搜索功能
Mar 06 Javascript
javascript 获取图片颜色
Apr 05 Javascript
jquery使用ColorBox弹出图片组浏览层实例演示
Mar 14 Javascript
ExtJs默认的字体大小改变的几种方法(自己整理)
Apr 18 Javascript
jQuery中last()方法用法实例
Jan 06 Javascript
javascript创建函数的20种方式汇总
Jun 23 Javascript
jQuery添加和删除指定标签的方法
Dec 16 Javascript
javascript实现禁止复制网页内容汇总
Dec 30 Javascript
浅谈angularjs中响应回车事件
Apr 24 Javascript
layui添加动态菜单与选项卡 AJAX请求的例子
Sep 25 Javascript
微信小程序实现点击导航标签滚动定位到对应位置
Nov 19 Javascript
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
Apr 24 Vue.js
使用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
通过缓存数据库结果提高PHP性能的原理介绍
2012/09/05 PHP
深入解析PHP 5.3.x 的strtotime() 时区设定 警告信息修复
2013/08/05 PHP
dedecms函数分享之获取某一栏目所有子栏目
2014/05/19 PHP
php简单计算页面加载时间的方法
2015/06/19 PHP
如何修改yii2.0自带的user表为其它的表
2017/08/01 PHP
laravel请求参数校验方法
2019/10/10 PHP
PHP高并发和大流量解决方案整理
2021/03/09 PHP
js实现的牛顿摆效果
2015/03/31 Javascript
AngularJS使用ng-options指令实现下拉框
2016/08/23 Javascript
js仿京东轮播效果 选项卡套选项卡使用
2017/01/12 Javascript
js es6系列教程 - 新的类语法实战选项卡(详解)
2017/09/02 Javascript
利用CDN加速react webpack打包后的文件详解
2018/02/22 Javascript
微信小程序实现通过双向滑动缩放图片大小的方法
2018/12/30 Javascript
详解JavaScript 的变量
2019/03/08 Javascript
js 获取扫码枪输入数据的方法
2020/06/10 Javascript
vue v-for出来的列表,点击某个li使得当前被点击的li字体变红操作
2020/07/17 Javascript
js用正则表达式筛选年月日的实例方法
2021/01/04 Javascript
Python标准库defaultdict模块使用示例
2015/04/28 Python
深度定制Python的Flask框架开发环境的一些技巧总结
2016/07/12 Python
python实现简单成绩录入系统
2019/09/19 Python
DHC中国官方购物网站:日本通信销售No.1化妆品
2016/08/20 全球购物
英国最大的在线床超市:Bed Star
2019/01/24 全球购物
美国名牌手表折扣网站:Jomashop
2020/05/22 全球购物
五年级科学教学反思
2014/02/05 职场文书
《唯一的听众》教学反思
2014/02/20 职场文书
低碳生活的宣传标语
2014/06/23 职场文书
环境监测与治理技术专业求职信
2014/07/06 职场文书
英语课外活动总结
2014/08/27 职场文书
大学生考试作弊检讨书
2014/09/21 职场文书
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
自主招生自荐信范文
2015/03/04 职场文书
2015年领导干部廉洁自律工作总结
2015/05/26 职场文书
2015年秋季学校开学标语
2015/07/16 职场文书
三八红旗手先进事迹材料(2016推荐版)
2016/02/25 职场文书
导游词之包公祠
2019/11/25 职场文书
使用Python开发贪吃蛇游戏 SnakeGame
2022/04/30 Python