手撸移动便签功能
实现原理
1.监听事件
1.监听触发移动区域元素鼠标按下事件:onmousedown
2.监听鼠标移动的事件
1.需要在整个可视化区域中移动
2.因此监听window的鼠标移动事件onmousemove
3.监听鼠标抬起事件
1.可视区域任意位置抬起时,终止
2.因此监听window的鼠标抬起事件onmouseup
3.销毁鼠标按下的事件,以及鼠标移动的监听事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var moveBar = document.querySelector( '.move-bar' ) var note = document.querySelector( '.note' ) console.log(moveBar, 'movebar' ) <br> moveBar.onmousedown= function (e){ //开启监听 window.onmousemove= function (e){ // console.log('鼠标在移动') } //绑定事件 window.onmouseup= function (){ // console.log('不再监听移动') } } |
2.计算位置
1.鼠标按下时位置
// var x = e.clientX
2.鼠标移动距离计算
移动x轴距离 = 当前鼠标x位置 - 初始鼠标x位置
移动y轴距离 = 当前鼠标y位置 - 初始鼠标y位置
3.便签需移动距离计算
移动元素左(x)边距= 移动元素原始左(x)边距 + 移动的x轴距离
移动元素上(y)边距 = 移动元素原始上(y)边距 + 移动的y轴距离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | var moveBar = document.querySelector( '.move-bar' ) var note = document.querySelector( '.note' ) console.log(moveBar, 'movebar' ) moveBar.onmousedown= function (e){ // //获取鼠标按下的坐标 var x = e.clientX var y = e.clientY // //获取元素坐标 var ract = moveBar.getBoundingClientRect() var ex = ract.left var ey = ract.top //绑定事件 window.onmousemove= function (e){ console.log( '鼠标在移动' ) var disX = e.clientX - x var disY = e.clientY -y var left = ex + disX var top = ey + disY console.log( left , top , disX ,disY ) note.style.left = left + 'px' note.style.top = top + 'px' } //绑定事件 window.onmouseup= function (){ console.log( '不再监听移动' ) // moveBar.onmousedown=null window.onmousemove = null window.onmouseup = null // moveBar.onmouseup =null } } |
3.移动边界限制
1.最左距离
移动元素左(x)边距 < 0 强制:限制移动元素左(x)边距 =0
2.最右距离
最大移动元素左(x)边距 = 可视区域宽度 - 移动元素本身宽度
3.最上距离
移动元素上(y)边距 < 0 强制:限制移动元素上(y)边距 =0
4.最下距离
最大移动元素上(y)边距 = 可视区域高度 - 移动元素本身高度
//完整版代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | var moveBar = document.querySelector( '.move-bar' ) var note = document.querySelector( '.note' ) console.log(moveBar, 'movebar' ) moveBar.onmousedown= function (e){ // //获取鼠标按下的坐标 var x = e.clientX var y = e.clientY // //获取元素坐标 var ract = moveBar.getBoundingClientRect() var ex = ract.left var ey = ract.top //获取视口宽高,元素宽高 var ew = note.offsetWidth var eh = note.offsetHeight var w = document.documentElement.clientWidth var h = document.documentElement.clientHeight console.log(w,h,ew,eh) //限定移动区域 var maxLeft = w -ew var maxTop = h- eh //绑定事件 window.onmousemove= function (e){ console.log( '鼠标在移动' ) var disX = e.clientX - x var disY = e.clientY -y var left = ex + disX var top = ey + disY console.log( left , top , disX ,disY ) //限定 if (left < 0){ left =0 } if (left >maxLeft){ left = maxLeft } if (top<0){ top =0 } if (top > maxTop){ top = maxTop } note.style.left = left + 'px' note.style.top = top + 'px' console.dir(note) } //绑定事件 window.onmouseup= function (){ console.log( '不再监听移动' ) // moveBar.onmousedown=null window.onmousemove = null window.onmouseup = null // moveBar.onmouseup =null } } |
//测试index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .note{ width: 200px; height: 200px; background-color: rgb(233, 223, 138); position: relative; } .move-bar{ height: 10px; background-color: rgb(196, 177, 14); cursor:move; } .content{ padding: 20px; box-sizing:content-box; } </style> </head> <body> <div class="note"> <div class="move-bar"></div> <div class="content"> <p>这是一个便签</p> <p>这是一个便签</p> <p>这是一个便签</p> <p>这是一个便签</p> </div> </div> <script src="./index.js"></script> </body> </html>
//测试 index.js
var moveBar = document.querySelector('.move-bar') var note = document.querySelector('.note') console.log(moveBar,'movebar') moveBar.onmousedown= function(e){ // //获取鼠标按下的坐标 var x = e.clientX var y = e.clientY // //获取元素坐标 var ract = moveBar.getBoundingClientRect() var ex = ract.left var ey = ract.top //获取视口宽高,元素宽高 var ew = note.offsetWidth var eh = note.offsetHeight var w = document.documentElement.clientWidth var h = document.documentElement.clientHeight console.log(w,h,ew,eh) //限定移动区域 var maxLeft = w -ew var maxTop = h- eh //绑定事件 window.onmousemove= function(e){ console.log('鼠标在移动') var disX = e.clientX - x var disY = e.clientY -y var left = ex + disX var top = ey + disY console.log( left , top , disX ,disY ) //限定 if(left < 0){ left =0 } if(left >maxLeft){ left = maxLeft } if(top<0){ top =0 } if(top > maxTop){ top = maxTop } note.style.left = left + 'px' note.style.top = top + 'px' console.dir(note) } //绑定事件 window.onmouseup= function(){ console.log('不再监听移动') // moveBar.onmousedown=null window.onmousemove = null window.onmouseup = null // moveBar.onmouseup =null } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通