JavaScript DOM 滑鼠拖拽
在前端頁面互動中,滑鼠拖拽是一個體驗良好的功能,實作滑鼠拖拽需要了解滑鼠行為坐標系和涉及到的許多兼容性寫法,本文介紹滑鼠位置的獲取和、拽功能的實作以及拖拽函式的封裝
滑鼠行為坐標系
-
滑鼠行為觸發事件時,事件物件上會有一些屬性提供滑鼠的位置資訊
屬性 功能 兼容性 clientX/Y 滑鼠相對可視區域的坐標 / x/y 與 clientX/Y 功能相同 firefox 低版本不支持 pageX/Y 滑鼠相對整個檔案的坐標 兼容 IE9 及以上 layerX/Y 與 pageX/Y 功能相同 IE10 及以下同 clientX/Y screenX/Y 滑鼠位置相對螢屏坐標 / offsetX/Y 滑鼠位置相對塊元素的坐標(包含邊框) safari 不包含邊框 -
獲取滑鼠相對整個檔案的坐標:pageX/Y 兼容性差,需要進行封裝
滑鼠相對整個檔案的坐標 = 滑鼠相對可視區域的坐標 + 滾動條滾動距離 - 檔案偏移
document.documentElement.clientTop 獲取檔案偏移,在 IE 一些版本中為 undefined
function pagePos(ev) { var sTop = getScrollOffset().top, sLeft = getScrollOffset().left, cTop = document.documentElement.clientTop || 0, cLeft = document.documentElement.clientLeft || 0; return { X: ev.clientX + sLeft - cLeft, Y: ev.clientY + sTop - cTop } } // 封裝的函式:獲取滾動條滾動距離 function getScrollOffset() { if (window.pageXOffset) { return { top: window.pageYOffset, left: window.pageXOffset } } else return { top:document.body.scrollTop || document.documentElement.scrollTop, left:document.body.scrollLeft || document.documentElement.scrollLeft } }
拖拽函式封裝
-
拖拽效果基于滑鼠事件:mousedown、mousemove、mouseup
分別為滑鼠按下、滑鼠移動、滑鼠松開
-
原理:滑鼠按下時,添加滑鼠移動、滑鼠松開的事件處理函式,滑鼠移動時獲取滑鼠坐標,改變元素樣式,滑鼠松開時清除滑鼠移動和滑鼠松開的事件處理函式
<!doctype html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>Index</title> <style type="text/css"> .box { position: absolute; top: 0; left: 0; width: 100px; height: 100px; background-color: red; } </style> </head> <body> <div ></div> <script> var box = document.getElementsByTagName('div')[0]; box.onmousedown = function (ev) { var ev = ev || window.event, x = pagePos(ev).X - parseInt(getStyles(box)['left']), y = pagePos(ev).Y - parseInt(getStyles(box)['top']); document.onmousemove = function (ev) { var ev = ev || window.event, mPos = pagePos(ev); box.style.left = mPos.X - x + 'px'; box.style.top = mPos.Y - y + 'px'; } document.onmouseup = function () { this.onmousemove = null; this.onmouseup = null; } } // 封裝的函式:獲取滑鼠相對整個檔案的坐標 function pagePos(ev) { var sTop = getScrollOffset().top, sLeft = getScrollOffset().left, cTop = document.documentElement.clientTop || 0, cLeft = document.documentElement.clientLeft || 0; return { X: ev.clientX + sLeft - cLeft, Y: ev.clientY + sTop - cTop } } // 封裝的函式:獲取滾動條滾動距離 function getScrollOffset() { if (window.pageXOffset) { return { top: window.pageYOffset, left: window.pageXOffset } } else return { top: document.body.scrollTop || document.documentElement.scrollTop, left: document.body.scrollLeft || document.documentElement.scrollLeft } } // 封裝的函式:獲取元素樣式的類陣列 function getStyles(elem) { if (window.getComputedStyle) { return window.getComputedStyle(elem, null); } else return elem.currentStyle; } </script> </body> </html> -
封裝拖拽函式
var box = document.getElementsByTagName('div')[0]; elemDrag(box); // 封裝的拖拽函式 function elemDrag(elem) { var x, y; addEvent(elem, 'mousedown', function (ev) { var ev = ev || window.event; x = pagePos(ev).X - parseInt(getStyles(elem)['left']); y = pagePos(ev).Y - parseInt(getStyles(elem)['top']); addEvent(document, 'mousemove', mousemove); addEvent(document, 'mouseup', mouseup); cancelBubble(ev); preventDefaultEvent(ev); }); function mousemove(ev) { var ev = ev || window.event; elem.style.left = pagePos(ev).X - x + 'px'; elem.style.top = pagePos(ev).Y - y + 'px'; } function mouseup(ev) { var ev = ev || window.event; removeEvent(document, 'mousemove', mousemove); removeEvent(document, 'mouseup', mouseup); } } // 系結事件處理函式 function addEvent(elem, type, fn) { if (elem.addEventListener) { elem.addEventListener(type, fn); } else if (elem.attachEvent) { elem.attachEvent('on' + type, function (ev) { fn.call(elem, ev); // call 兼容性比 bind 好 }); } else { elem['on' + type] = fn; } } // 解綁事件處理函式 function removeEvent(elem, type, fn) { if (elem.addEventListener) { elem.removeEventListener(type, fn); } else if (elem.attachEvent) { elem.detachEvent('on' + type, fn); } else { elem['on' + type] = null; } } // 獲取滑鼠在整個檔案中的坐標 function pagePos(ev) { var sTop = getScrollOffset().top, sLeft = getScrollOffset().left, cTop = document.documentElement.clientTop || 0, cLeft = document.documentElement.clientLeft || 0; return { X: ev.clientX + sLeft - cLeft, Y: ev.clientY + sTop - cTop } } // 獲取滾動條滾動距離 function getScrollOffset() { if (window.pageXOffset) { return { top: window.pageYOffset, left: window.pageXOffset } } else return { top: document.body.scrollTop || document.documentElement.scrollTop, left: document.body.scrollLeft || document.documentElement.scrollLeft } } // 獲取元素樣式的類陣列 function getStyles(elem) { if (window.getComputedStyle) { return window.getComputedStyle(elem, null); } else return elem.currentStyle; } // 阻止冒泡 function cancelBubble(ev) { if (ev.stopPropagation) { ev.stopPropagation(); } else ev.cancelBubble = true; // 兼容 IE8 及以下 } // 阻止默認事件 function preventDefaultEvent(ev) { if (ev.preventDefault) { ev.preventDefault(); } else ev.returnValue = https://www.cnblogs.com/cadecode/p/false; // 兼容 IE8 及以下 }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/135971.html
標籤:JavaScript
