js 实现 pc 端 拖拽效果
点击目录标题预览效果
单个元素拖拽,不随页面滚动
css 部分
body{height:2000px;} div{width:150px; height:150px;cursor: move;position: fixed;top:50px;color:#fff;box-sizing: border-box;z-index: 10;font-size: 16px} #ele{background:#2196f3;left:10px; }
js 部分
window.onload=function(){ // 获取元素 var Div=document.getElementById('ele'); drag(Div); }

1 // 拖拽运动 2 function drag(obj){ 3 4 var lastX=0; 5 var lastY=0; 6 // ev 为系统自带参数 7 obj.onmousedown=function(ev) 8 { 9 var Ev=ev||event; // FF || IE 10 var disX=Ev.clientX-parseInt(getStyle(obj,'left')); 11 var disY=Ev.clientY-parseInt(getStyle(obj,'top')); 12 13 //事件捕获,设置页面鼠标事件集中到 拖拽元素上,针对低版本IE 14 if(obj.setCapture) 15 { 16 //两种写法都可以,document 是防止鼠标拖拽过快,obj 跟不上 鼠标 17 // 由于设置事件捕获,所以对象 可以设置为 obj, 应用于低版本IE 18 // document.onmousemove=Move; 19 // document.onmouseup=Up; 20 obj.onmousemove=Move; 21 obj.onmouseup=Up; 22 obj.setCapture(); 23 } 24 else 25 { 26 document.onmousemove=Move; 27 document.onmouseup=Up; 28 } 29 // 鼠标移动,函数上的 ev 参数是系统传过来的 30 function Move(ev) 31 { 32 var Ev=ev||event; // FF || IE 33 var l=Ev.clientX-disX; 34 var t=Ev.clientY-disY; 35 36 37 if(l>=document.documentElement.clientWidth-parseInt(getStyle(obj,'width'))) 38 { 39 l=document.documentElement.clientWidth-parseInt(getStyle(obj,'width')); 40 } 41 else if(l<=0) 42 { l=0; } 43 44 if(t>=document.documentElement.clientHeight-parseInt(getStyle(obj,'height'))) 45 { 46 t=document.documentElement.clientHeight-parseInt(getStyle(obj,'height')); 47 } 48 else if(t<=0) 49 { t=0; } 50 51 lastX=l; 52 lastY=t; // 当前的点赋给一个变量(上一个点) 53 obj.style.left=l+'px'; 54 obj.style.top=t+'px'; //移动物体 55 } 56 // 鼠标抬起 57 function Up() 58 { 59 document.onmousemove=null; 60 document.onmouseup=null; 61 // 释放捕获 62 if(obj.releaseCapture) 63 { obj.releaseCapture(); } 64 65 } 66 // 解决 chrome ff IE9 浏览器拖拽时选择文字、内容问题 67 return false; 68 } 69 } 70 71 //提取非行间样式 72 function getStyle(obj,attr) 73 { 74 if(obj.currentStyle) 75 { return obj.currentStyle[attr];} 76 else 77 { return getComputedStyle(obj,false)[attr];} 78 }
html 部分
<body> <div id="ele">单个退拽元素<br/>原生js<br/>不跟随页面滚动</div> </body>
多个元素拖拽,不随页面滚动
css 部分
body{height:2000px;} div{width:150px; height:150px;cursor: move;position: fixed;top:50px;color:#fff;box-sizing: border-box;z-index: 10;font-size: 16px} #ele1{background:#2196f3;left:10px; } #ele2{background:#ff5722;left:180px;} #ele3{background:#08c80f;left:360px; }
js 部分
window.onload=function(){ //获取拖拽的元素 var ele1=document.getElementById('ele1'); var ele2=document.getElementById('ele2'); var ele3=document.getElementById('ele3'); // 层级问题默认 ele1:1,ele2:2,ele3:3 // 定义公共层级变量,3个定义的一样,这里取了第一个 this.layer=parseInt(getStyle(ele1,'z-index')) drag(ele1); drag(ele2); drag(ele3); }

1 // 拖拽运动 2 function drag(obj){ 3 var lastX=0; 4 var lastY=0; 5 6 // ev 为系统自带参数 7 obj.onmousedown=function(ev) 8 { 9 var Ev=ev||event; // FF || IE 10 var disX=Ev.clientX-parseInt(getStyle(obj,'left')); 11 var disY=Ev.clientY-parseInt(getStyle(obj,'top')); 12 // 层级问题,最后拖拽的在最上面,由于 zIndex 最大值是一个非常大的数,所以这里没有限制处理 13 obj.style.zIndex=window.layer=window.layer+1 14 15 //事件捕获,设置页面鼠标事件集中到 拖拽元素上 针对IE 16 if(obj.setCapture) 17 { 18 document.onmousemove=Move; 19 document.onmouseup=Up; 20 obj.setCapture(); 21 } 22 else 23 { 24 document.onmousemove=Move; 25 document.onmouseup=Up; 26 } 27 // 鼠标移动 28 function Move(ev) 29 { 30 var Ev=ev||event; 31 var l=Ev.clientX-disX; 32 var t=Ev.clientY-disY; 33 34 if(l>=document.documentElement.clientWidth-parseInt(getStyle(obj,'width'))) 35 { 36 l=document.documentElement.clientWidth-parseInt(getStyle(obj,'width')); 37 } 38 else if(l<=0) 39 { l=0; } 40 41 if(t>=document.documentElement.clientHeight-parseInt(getStyle(obj,'height'))) 42 { 43 t=document.documentElement.clientHeight-parseInt(getStyle(obj,'height')); 44 } 45 else if(t<=0) 46 { t=0; } 47 48 lastX=l; 49 lastY=t; // 当前的点赋给一个变量(上一个点) 50 obj.style.left=l+'px'; 51 obj.style.top=t+'px'; //移动物体 52 } 53 // 鼠标抬起 54 function Up() 55 { 56 document.onmousemove=null; 57 document.onmouseup=null; 58 // 释放事件捕获 59 if(obj.releaseCapture) 60 { obj.releaseCapture(); } 61 62 } 63 return false; // 解决 chrome ff IE9 浏览器拖拽时选择文字、内容问题 64 } 65 } 66 67 //提取非行间样式 68 function getStyle(obj,attr) 69 { 70 if(obj.currentStyle) 71 { return obj.currentStyle[attr];} 72 else 73 { return getComputedStyle(obj,false)[attr];} 74 }
html 部分
<body> <div id="ele1">多个退拽元素<br/>原生js<br/>不跟随页面滚动<br/>最后拖拽的在最上面</div> <div id="ele2">多个退拽元素<br/>原生js<br/>不跟随页面滚动<br/>最后拖拽的在最上面</div> <div id="ele3">多个退拽元素<br/>原生js<br/>不跟随页面滚动<br/>最后拖拽的在最上面</div> </body>
单个元素拖拽,添加选项配置
css 部分
/*body{height:2000px;width:2000px;}*/ *{margin:0px;padding:0px;} p{margin:150px; } /*如果父元素不是body,建议手动指定 left top 值,如果不指定 默认 bottom:0; left:50( 我这里设置margin:50 原因); */ #warp{width:500px;height:500px;border: 1px #ccc solid;margin:50px; background: #fff;left:50px;top:50px;} #ele{width:150px; height:150px;cursor: move;color:#fff;box-sizing: border-box;z-index: 10;font-size: 16px;background:#2196f3; }
js 部分
配置参数:
top,bottom,left,right 默认值为 0 ,拖拽元素 距离 范围元素(默认body) 的距离
direction 拖拽方向,默认为任意方向,lr(左右) tb(上下)
parent:'warp', 为页面唯一元素,拖拽元素活动范围 元素,id 名称,例如 warp ,默认body整个页面
scroll:false 拖拽元素是否随 页面滚动 false 不随页面滚动,true 随页面滚动
window.onload=function(){ // 配置选项 var opt={ top:0, bottom:0, left:20, right:10, parent:'warp', // 为页面唯一元素,id 名称,例如 warp ,默认body整个页面 scroll:false // 拖拽元素是否随 页面滚动 false 不随页面滚动,true 随页面滚动 } var obj=document.getElementById('ele'); // 调用退拽函数 drag(obj,opt); }

1 // 拖拽运动 2 function drag(obj,opt={},){ 3 // 默认配置选项 4 var option={ 5 direction:'auto',//方向 lr(左右) tb(上下) 6 // 运动范围 默认父级边界 7 top:0, 8 bottom:0, 9 left:0, 10 right:0, 11 //parent:'warp', // 为页面唯一元素,id 名称,例如 warp ,默认body整个页面 12 scroll:false // 拖拽元素是否随 页面滚动 false 不随页面滚动,true 随页面滚动 13 } 14 // 合并对象参数 15 Object.assign(option,opt) 16 17 var lastX=0; 18 var lastY=0; 19 var parent_width=0,parent_height=0,parent_left=0,parent_top=0; 20 var ele_position='fixed' 21 if(option.scroll){ 22 ele_position='absolute' 23 }else{ 24 // 如果不跟随页面滚动,并且元素父级不是body,父元素定位, 25 if(option.parent) 26 document.getElementById(option.parent).style.position='fixed' 27 } 28 29 // 设置元素的定位,需要放置获取 parent_* 值之前 30 obj.style.position=ele_position 31 32 if(option.parent){ 33 var parent_ele=document.getElementById(option.parent) 34 parent_width=parent_ele.clientWidth; 35 parent_height=parent_ele.clientHeight; 36 parent_left=parent_ele.offsetLeft; 37 parent_top=parent_ele.offsetTop; 38 }else{ 39 if(option.scroll){ 40 parent_width=document.documentElement.scrollWidth 41 parent_height=document.documentElement.scrollHeight 42 }else{ 43 parent_width=document.documentElement.clientWidth 44 parent_height=document.documentElement.clientHeight 45 } 46 } 47 48 // 设置元素位置 49 obj.style.left=option.left+parent_left+'px' 50 obj.style.top=option.top+parent_top+'px' 51 52 obj.onmousedown=function(ev) 53 { 54 var Ev=ev||event; 55 var disX=0,disY=0; 56 57 if(option.direction=="lr"){ 58 disX=Ev.clientX-parseInt(getStyle(obj,'left')); 59 }else if(option.direction=="tb"){ 60 disY=Ev.clientY-parseInt(getStyle(obj,'top')); 61 }else{ 62 disX=Ev.clientX-parseInt(getStyle(obj,'left')); 63 disY=Ev.clientY-parseInt(getStyle(obj,'top')); 64 } 65 66 if(obj.setCapture)//设置鼠标捕获 针对IE 67 { 68 document.onmousemove=Move; 69 document.onmouseup=Up; 70 obj.setCapture(); 71 }else 72 { 73 document.onmousemove=Move; 74 document.onmouseup=Up; 75 } 76 // 鼠标移动 77 function Move(ev) 78 { 79 var Ev=ev||event; 80 var left=0,top=0,move_left=0,move_top=0 81 if(option.direction=="lr"){ 82 // 可移动的最大左边距离 83 move_left=parent_width-parseInt(getStyle(obj,'width'))-option.right+parent_left 84 if(left>=move_left){ 85 left=move_left 86 }else if(left<=option.left+parent_left){ 87 left=option.left+parent_left 88 }else{ 89 left=Ev.clientX-disX; 90 } 91 lastX=left; 92 obj.style.left=left+'px'; 93 94 }else if(option.direction=="tb"){ 95 // 可以移动的最大上边距 96 move_top=parent_height-parseInt(getStyle(obj,'height'))-option.top+parent_top 97 if(top>=move_top){ 98 top=move_top 99 }else if(top<=option.bottom+parent_top){ 100 top=option.bottom 101 }else{ 102 top=Ev.clientY-disY; 103 } 104 lastY=top; 105 obj.style.top=top+'px'; 106 }else{ 107 left=Ev.clientX-disX; 108 top=Ev.clientY-disY; 109 110 move_left=parent_width-parseInt(getStyle(obj,'width'))-option.right+parent_left 111 move_top=parent_height-parseInt(getStyle(obj,'height'))-option.bottom+parent_top 112 113 if(left>=move_left){ 114 left=move_left 115 }else if(left<=option.left+parent_left){ 116 left=option.left+parent_left 117 } 118 if(top>=move_top){ 119 top=move_top 120 }else if(top<=option.bottom+parent_top){ 121 top=option.bottom+parent_top 122 } 123 124 lastX=left; 125 lastY=top; // 当前的点赋给一个变量(上一个点) 126 obj.style.left=left+'px'; 127 obj.style.top=top+'px'; //移动物体 128 } 129 } 130 // 鼠标抬起 131 function Up() 132 { 133 document.onmousemove=null; 134 document.onmouseup=null; 135 //释放捕获 136 if(obj.releaseCapture) 137 { obj.releaseCapture(); } 138 139 } 140 return false; 141 }// onmousedown 结束 142 } 143 144 //提取非行间样式 145 function getStyle(obj,attr) 146 { 147 if(obj.currentStyle) 148 { return obj.currentStyle[attr];} 149 else 150 { return getComputedStyle(obj,false)[attr];} 151 }
html 部分
<body> <div id="warp"><p>指定元素内拖拽</p></div> <p>测试部分</p> <div id="ele">单个退拽元素<br/>原生js<br/>添加配置选项</div> <p>测试部分</p> </body>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现