Last active
          April 4, 2018 09:25 
        
      - 
      
 - 
        
Save JSoon/ec347df594a80fd5ab9a266d7e3cb501 to your computer and use it in GitHub Desktop.  
    JavaScript 简单拖拽
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
| <title>拖拽</title> | |
| <style> | |
| html, | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| } | |
| #dragEle { | |
| width: 200px; | |
| height: 150px; | |
| background: red; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="dragEle"></div> | |
| <script> | |
| // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Notes | |
| // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/attachEvent | |
| //#region IE 8 support | |
| (function () { | |
| if (!Event.prototype.preventDefault) { | |
| Event.prototype.preventDefault = function () { | |
| this.returnValue = false; | |
| }; | |
| } | |
| if (!Event.prototype.stopPropagation) { | |
| Event.prototype.stopPropagation = function () { | |
| this.cancelBubble = true; | |
| }; | |
| } | |
| if (!Element.prototype.addEventListener) { | |
| var eventListeners = []; | |
| var addEventListener = function (type, listener /*, useCapture (will be ignored) */ ) { | |
| var self = this; | |
| var wrapper = function (e) { | |
| e.target = e.srcElement; | |
| e.currentTarget = self; | |
| if (typeof listener.handleEvent != 'undefined') { | |
| listener.handleEvent(e); | |
| } else { | |
| listener.call(self, e); | |
| } | |
| }; | |
| if (type == "DOMContentLoaded") { | |
| var wrapper2 = function (e) { | |
| if (document.readyState == "complete") { | |
| wrapper(e); | |
| } | |
| }; | |
| document.attachEvent("onreadystatechange", wrapper2); | |
| eventListeners.push({ | |
| object: this, | |
| type: type, | |
| listener: listener, | |
| wrapper: wrapper2 | |
| }); | |
| if (document.readyState == "complete") { | |
| var e = new Event(); | |
| e.srcElement = window; | |
| wrapper2(e); | |
| } | |
| } else { | |
| this.attachEvent("on" + type, wrapper); | |
| eventListeners.push({ | |
| object: this, | |
| type: type, | |
| listener: listener, | |
| wrapper: wrapper | |
| }); | |
| } | |
| }; | |
| var removeEventListener = function (type, listener /*, useCapture (will be ignored) */ ) { | |
| var counter = 0; | |
| while (counter < eventListeners.length) { | |
| var eventListener = eventListeners[counter]; | |
| if (eventListener.object == this && eventListener.type == type && eventListener.listener == | |
| listener) { | |
| if (type == "DOMContentLoaded") { | |
| this.detachEvent("onreadystatechange", eventListener.wrapper); | |
| } else { | |
| this.detachEvent("on" + type, eventListener.wrapper); | |
| } | |
| eventListeners.splice(counter, 1); | |
| break; | |
| } | |
| ++counter; | |
| } | |
| }; | |
| Element.prototype.addEventListener = addEventListener; | |
| Element.prototype.removeEventListener = removeEventListener; | |
| if (HTMLDocument) { | |
| HTMLDocument.prototype.addEventListener = addEventListener; | |
| HTMLDocument.prototype.removeEventListener = removeEventListener; | |
| } | |
| if (Window) { | |
| Window.prototype.addEventListener = addEventListener; | |
| Window.prototype.removeEventListener = removeEventListener; | |
| } | |
| } | |
| })(); | |
| //#endregion | |
| var dom = document.getElementById('dragEle'); // 拖拽区DOM节点 | |
| var domW = dom.clientWidth; // 拖拽节点宽度(包含padding) | |
| var domH = dom.clientHeight; // 拖拽节点高度(包含padding) | |
| var domPointL; // 鼠标相对拖拽区域的左边距 | |
| var domPointR; // 鼠标相对拖拽区域的右边距 | |
| var domPointT; // 鼠标相对拖拽区域的上边距 | |
| var domPointB; // 鼠标相对拖拽区域的下边距 | |
| var dragEndFlag = true; // 拖拽是否已经结束(即鼠标松开,默认结束) | |
| document.addEventListener('mousedown', dragStart, false); // 鼠标按下,拖拽开始 | |
| document.addEventListener('mouseup', dragEnd, false); // 鼠标松开,拖拽结束 | |
| document.addEventListener('mouseenter', dragMouseEnter, false); // 鼠标进入拖拽区 | |
| document.addEventListener('mouseleave', dragMouseLeave, false); // 鼠标离开拖拽区 | |
| function dragStart(e) { | |
| // 若鼠标按下的坐标不在拖拽区,则不进行拖拽 | |
| // https://stackoverflow.com/questions/2642095/access-event-target-in-ie8-unobstrusive-javascript | |
| // https://stackoverflow.com/questions/19371589/onchange-event-object-undefined-in-ie8 | |
| e = e || window.event; // get window.event if argument is falsy (in IE) | |
| e.target = e.target || e.srcElement; // get srcElement if target is falsy (IE) | |
| if (e.target !== dom) { | |
| return; | |
| } | |
| // 鼠标初始拖拽点(相对于body) | |
| var x = e.clientX; // 鼠标处据body左边距 | |
| var y = e.clientY; // 鼠标处据body上边距 | |
| // console.log(x, y); | |
| // 鼠标初始拖拽点(相对于拖拽区域) | |
| var domX = dom.offsetLeft; // 拖拽节点距body左边距 | |
| var domY = dom.offsetTop; // 拖拽节点距body上边距 | |
| domPointL = x - domX; | |
| domPointR = domW - domPointL; | |
| domPointT = y - domY; | |
| domPointB = domH - domPointT; | |
| document.addEventListener('mousemove', dragMove, false); | |
| } | |
| function dragEnd(e) { | |
| dragEndFlag = true; | |
| document.removeEventListener('mousemove', dragMove, false); | |
| } | |
| function dragMove(e) { | |
| var x = e.clientX; // 鼠标处距body左边距 | |
| var y = e.clientY; // 鼠标处距body上边距 | |
| // console.log(x, y); | |
| var domW = dom.clientWidth; // 拖拽节点宽度(包含padding) | |
| var domH = dom.clientHeight; // 拖拽节点高度(包含padding) | |
| var domX = dom.offsetLeft; // 拖拽节点距body左边距 | |
| var domY = dom.offsetTop; // 拖拽节点距body上边距 | |
| var viewportW = document.documentElement.clientWidth; // 窗口可视区域宽度 | |
| var viewportH = document.documentElement.clientHeight; // 窗口可视区域高度 | |
| // 移动拖拽节点 | |
| dom.style.position = 'fixed'; | |
| /** | |
| * 限定拖拽节点的活动范围只能在浏览器窗口可视区域中 | |
| * | |
| * 拖拽节点在可视区域中判断条件: | |
| * 1. 鼠标相对浏览器窗口的左边距 - 相对拖拽区域的左边距 > 0 | |
| * 2. 鼠标相对浏览器窗口的左边距 + 相对拖拽区域的右边距 < 可视区域宽度 | |
| * 3. 鼠标相对浏览器窗口的上边距 - 相对拖拽区域的上边距 > 0 | |
| * 4. 鼠标相对浏览器窗口的上边距 + 相对拖拽区域的上边距 < 可视区域高度 | |
| * 5. 若非情况1,则拖拽节点左边距 = 0 | |
| * 6. 若非情况2,则拖拽节点左边距 = 可视区域宽度 - 拖拽节点宽度 | |
| * 5. 若非情况3,则拖拽节点上边距 = 0 | |
| * 5. 若非情况4,则拖拽节点上边距 = 可视区域高度 - 拖拽节点高度 | |
| */ | |
| // 限定x轴上的移动 | |
| if (x - domPointL > 0 && x + domPointR < viewportW) { | |
| dom.style.left = x - domPointL + 'px'; | |
| } else if (x - domPointL <= 0) { | |
| dom.style.left = 0 + 'px'; | |
| } else if (x + domPointR >= viewportW) { | |
| dom.style.left = viewportW - domW + 'px'; | |
| } | |
| // 限定y轴上的移动 | |
| if (y - domPointT > 0 && y + domPointB < viewportH) { | |
| dom.style.top = y - domPointT + 'px'; | |
| } else if (y - domPointT <= 0) { | |
| dom.style.top = 0 + 'px'; | |
| } else if (y + domPointB >= viewportH) { | |
| dom.style.top = viewportH - domH + 'px'; | |
| } | |
| dragEndFlag = false; | |
| } | |
| function dragMouseEnter(e) { | |
| // 若拖拽已结束,则不进行拖拽操作 | |
| if (dragEndFlag) { | |
| return; | |
| } | |
| document.addEventListener('mousemove', dragMove, false); | |
| } | |
| function dragMouseLeave(e) { | |
| document.removeEventListener('mousemove', dragMove, false); | |
| } | |
| </script> | |
| </body> | |
| </html> | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment
  
            
新增IE8兼容代码