鼠標捕獲(setCapture)作用是將鼠標事件捕獲到當前文檔的指定的對象——對指定的對象設置鼠標捕獲。這個對象會為當前應用程序或整個系統接收所有鼠標事件。
- 所謂鼠標捕獲,是指對鼠標事件(onmousedown, onmouseup, onmousemove, onclick, ondblclick, onmouseover, onmouseout)進行捕捉,使在容器內的子對象的鼠標事件均由容器對象觸發,因此,只能在容器對象的鼠標事件函數中進行處理。
- 當參數為true時,對鼠標進行捕捉,相反,不捕捉。
- 與這個函數對應,releaseCapture方法釋放鼠標捕獲,並觸發onlosecapture事件。
一、語法
1. MDN(Mozilla Developer Network)
element.setCapture(retargetToElement);
retargetToElement——If true, all events are targeted directly to this element; if false, events can also fire at descendants of this element.
document.releaseCapture()
釋放鼠標捕捉——Once mouse capture is released, mouse events will no longer all be directed to the element on which capture is enabled.
2. msdn(Internet Explorer Dev Center)
object.setCapture(containerCapture)
- 其中: containerCapture [in, optional]—— Type: Boolean
-
- true (true)——Default. 容器會捕獲容器內所有對象的鼠標事件,即容器內的對象不會觸發鼠標事件(跟容器外的對象一樣)Events originating in a container are captured by the container.
- false (false)——容器不會捕獲容器內對象的鼠標事件,即容器內的對象可以正常地觸發事件和取消冒泡。Events originating in a container are not captured by the container.
object.setCapture() 當一個object的被 setCapture 后,他的方法將會被繼承到整個文檔進行捕獲。當不需要把方法繼承到整個文檔捕獲時,要用 object.releaseCapture() 來釋放.
二、案例——簡單拖拽
完整代碼
<!DOCTYPE html> <html> <head> <title>drag example</title> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <style type="text/css"> #drag{position:absolute;left:12px;top:24px;width:100px;height:150px; display:block;border:1px solid #000000;z-index:1;background:#eeeeee; cursor: pointer;} </style> </head> <body> <div id="drag">drag me</div> <script type="text/javascript"> window.onload=function(){ objDiv = document.getElementById("drag"); drag(objDiv); }; function drag(dv){ dv.onmousedown=function(e){ var d=document; e = e || window.event; var x= e.layerX || e.offsetX; var y= e.layerY || e.offsetY; //設置捕獲范圍 if(dv.setCapture){ dv.setCapture(); }else if(window.captureEvents){ window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP); } d.onmousemove=function(e){ e= e || window.event; if(!e.pageX)e.pageX=e.clientX; if(!e.pageY)e.pageY=e.clientY; document.getElementById("drag").innerHTML= e.pageX+ e.pageY; var tx=e.pageX-x; var ty=e.pageY-y; dv.style.left=tx+"px"; dv.style.top=ty+"px"; }; d.onmouseup=function(){ //取消捕獲范圍 if(dv.releaseCapture){ dv.releaseCapture(); }else if(window.captureEvents){ window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP); } //清除事件 d.onmousemove=null; d.onmouseup=null; }; }; } </script> </body> </html>
三、案例——完美拖拽
完整代碼
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>完美拖拽</title> <style type="text/css"> html,body{overflow:hidden;} body,div,h2,p{margin:0;padding:0;} body{color:#fff;background:#000;font:12px/2 Arial;} p{padding:0 10px;margin-top:10px;} span{color:#ff0;padding-left:5px;} #box{position:absolute;width:300px;height:150px;background:#333;border:2px solid #ccc;top:50%;left:50%;margin:-75px 0 0 -150px;} #box h2{height:25px;cursor:move;background:#222;border-bottom:2px solid #ccc;text-align:right;padding:0 10px;} #box h2 a{color:#fff;font:12px/25px Arial;text-decoration:none;outline:none;} </style> <script type="text/javascript"> window.onload=function (){ var oBox=document.getElementById("box"); var oH2 = oBox.getElementsByTagName("h2")[0]; var oA = oBox.getElementsByTagName("a")[0]; var aSpan = oBox.getElementsByTagName("span"); var disX = disY = 0; var bDrag = false; var aPos = [{x:oBox.offsetLeft, y:oBox.offsetTop}]; //鼠標按下, 激活拖拽 oH2.onmousedown = function (event){ var event = event || window.event; bDrag = true; disX = event.clientX - oBox.offsetLeft; disY = event.clientY - oBox.offsetTop; aPos.push({x:oBox.offsetLeft, y:oBox.offsetTop}) this.setCapture && this.setCapture(); return false; }; //拖拽開始 document.onmousemove = function (event){ if (!bDrag) return; var event = event || window.event; var iL = event.clientX - disX; var iT = event.clientY - disY; var maxL = document.documentElement.clientWidth - oBox.offsetWidth; var maxT = document.documentElement.clientHeight - oBox.offsetHeight; iL = iL < 0 ? 0 : iL; iL = iL > maxL ? maxL : iL; iT = iT < 0 ? 0 : iT; iT = iT > maxT ? maxT : iT; oBox.style.marginTop = oBox.style.marginLeft = 0; oBox.style.left = iL + "px"; oBox.style.top = iT + "px"; aPos.push({x:iL, y:iT}) status(); return false; }; //鼠標釋放, 結束拖拽 document.onmouseup = window.onblur = oH2.onlosecapture = function (){ bDrag = false; oH2.releaseCapture && oH2.releaseCapture(); status(); }; //回放拖動軌跡 oA.onclick = function (){ if (aPos.length == 1) return; var timer = setInterval(function () { var oPos = aPos.pop(); oPos ? (oBox.style.left = oPos.x + "px", oBox.style.top = oPos.y + "px", status()) : clearInterval(timer) }, 30); this.focus = false;//去除鏈接虛線 return false; }; //阻止冒泡 oA.onmousedown = function (event){ (event || window.event).cancelBubble = true }; //監聽狀態函數 function status (){ aSpan[0].innerHTML = bDrag; aSpan[1].innerHTML = oBox.offsetTop; aSpan[2].innerHTML = oBox.offsetLeft; } //初始調用 status(); }; </script> </head> <body> <div id="box"> <h2><a href="javascript:;">點擊回放拖動軌跡</a></h2> <p><strong>Drag:</strong><span></span></p> <p><strong>offsetTop:</strong><span></span></p> <p><strong>offsetLeft:</strong><span></span></p> </div> </body> </html>
javascript代碼
//鼠標按下, 激活拖拽 oH2.onmousedown = function (event){ var event = event || window.event; bDrag = true; disX = event.clientX - oBox.offsetLeft; disY = event.clientY - oBox.offsetTop; aPos.push({x:oBox.offsetLeft, y:oBox.offsetTop}); this.setCapture && this.setCapture(); return false; }; //拖拽開始 document.onmousemove = function (event){ if (!bDrag) return; var event = event || window.event; var iL = event.clientX - disX; var iT = event.clientY - disY; var maxL = document.documentElement.clientWidth - oBox.offsetWidth; var maxT = document.documentElement.clientHeight - oBox.offsetHeight; iL = iL < 0 ? 0 : iL; iL = iL > maxL ? maxL : iL; iT = iT < 0 ? 0 : iT; iT = iT > maxT ? maxT : iT; oBox.style.marginTop = oBox.style.marginLeft = 0; oBox.style.left = iL + "px"; oBox.style.top = iT + "px"; aPos.push({x:iL, y:iT}) status(); return false; }; //鼠標釋放, 結束拖拽 document.onmouseup = window.onblur = oH2.onlosecapture = function (){ bDrag = false; oH2.releaseCapture && oH2.releaseCapture(); status(); }; //阻止冒泡 oA.onmousedown = function (event){ (event || window.event).cancelBubble = true }; //監聽狀態函數 function status (){ aSpan[0].innerHTML = bDrag; aSpan[1].innerHTML = oBox.offsetTop; aSpan[2].innerHTML = oBox.offsetLeft; }
參考:
- https://developer.mozilla.org/en-US/docs/Web/API/Element.setCapture
- http://msdn.microsoft.com/en-us/library/ie/ms536742%28v=vs.85%29.aspx
