本人在学习JavaScript事件注册、事件传递时,在网上找了一个很经典的窗口拖拽事例,其中牵扯到x、clientX、screenX等属性的区别,相信很多学习者在看到这个事例后,也查阅了许多相关材料,在此我也结合该事例,讲讲自己的理解。
首先给出该拖拽事例代码:
<html> <head> <title>空谷悠悠</title> <script type="text/javascript" > function beginDrag(elementToDrag,event) { //该元素当前位于何处 //该元素的样式性质必须具有left和top css属性 //此外,我们假定他们用象素做单位 //var x=parseInt(elementToDrag.style.left); //var y=parseInt(elementToDrag.style.top); //计算一个点(这个点应该是窗口第一次的坐标点)和鼠标点击之间的距离,下面的嵌套的moveHandler函数需要这些值 // var deltaX=event.clientX-parseInt(elementToDrag.style.left);style.left返回的是字符串,如28px,offsetLeft返回的是数值28,如果需要对取得的值进行计算,还是用offsetLeft比较方便 var deltaX = event.clientX-elementToDrag.offsetLeft; var deltaY=event.clientY-parseInt(elementToDrag.style.top); // 注册mousedown事件后发生的mousemove和mouseup事件的处理程序 // 注意,它们被注册为文档的捕捉事件处理程序 // 在鼠标按钮保持按下的状态的时候,这些事件处理程序保持活动的状态 // 在按钮被释放的时候,它们被删除 document.attachEvent("onmousemove",moveHandler); document.attachEvent("onmouseup",upHandler); //我们已经处理了该事件,不要让别的元素看到它 event.cancelBubble=true; event.returnValue=false; /* 这是在元素被拖动时候捕捉mousemove事件的处理程序,它响应移动的元素 */ function moveHandler() { //把元素移动到当前的鼠标位置 // e=window.event; elementToDrag.style.left=(event.clientX-deltaX)+"px"; elementToDrag.style.top=(event.clientY-deltaY)+"px"; //不要让别的元素看到该事件 event.cancelBubble=true; } /* 该事件将捕捉拖动结束的时候发生的mouseup事件 */ function upHandler() { //注销事件处理程序 document.detachEvent("onmouseup",upHandler); document.detachEvent("onmousemove",moveHandler); } event.cancelBubble=true; } </script> </head> <body > <div style="position:absolute;left:100px;top:100px;background-color:White;border:solid black;"> <div style="background-color:Gray;border-bottom:solid black;padding:3px;font-family:Sans-Serif;font-weight:bold;" onmousedown="beginDrag(this.parentNode,event);"> 拖动我 </div> <div> <p>This is a test.Testing,testing</p></div> </div> </body> </html>
在做窗口拖拽时,很关键的是准确得到坐标点,这里var deltaX = event.clientX-elementToDrag.offsetLeft;这段码求出了x轴坐标点的该变量,也就是因为这些,本文并不详解事件注册,冒泡机制,因为注释也写的比较详细了。本文要做的就是在代码的基础上,解释x、clientX、screenX等属性的区别。看如下代码:
<html> <script> function beginDrag(elementToDrag,event){ // parseInt(elementToDrag.style.left)等价于elementToDrag.offsetLeft, //因为style.left返回的是字符串,如28px,因此需要解析为数字 var deltaX = event.clientX-elementToDrag.offsetLeft; var deltaY = event.clientY-elementToDrag.offsetTop; //注册mousedown事件后,要发生的mousemove和mouseup事件的处理程序 document.attachEvent("onmousemove",moveHandler); document.attachEvent("onmouseup",upHandler); // 我们已经处理了该事件,不要让别的元素看到它 event.cancelBubble=true; event.returnValue =false; function moveHandler(){ elementToDrag.style.left = (event.clientX-deltaX)+"px"; elementToDrag.style.top =(event.clientY-deltaY)+"px"; event.cancelBubble=true; } function upHandler(){ document.detachEvent("onmouseup",upHandler); document.detachEvent("onmousemove",moveHandler); } event.cancelBubble = true; } function clientCoords(){ var offsetInfo = ""; offsetInfo += "The clientx coordinate is :"+window.event.clientX+"\r" offsetInfo += "The clienty coordinate is :"+window.event.clientY+"\r" offsetInfo +="The offsetX is :"+window.event.offsetX+"\r" offsetInfo +="The screenX is :"+window.event.screenX+"\r" alert(offsetInfo); } </script> <body onclick="clientCoords()" onmousemove= "window.status='clientX='+window.event.clientX+'clientY='+window.event.clientY"> <div style="position:absolute;left:100px;top:100px;background-color:White;border:solid black;" onmousedown="beginDrag(this,event)" name="div1"> <div style="background-color:blue;border-bottom:solid black;padding:3px;font-family:Sans-Serif;font-weight:bold;" name="div2" onmousedown="beginDrag(this.parentNode,event);"> 拖动我 </div> <div> <p>This is a test.Testing,testing</p></div> </div> </body></html>
随意点击窗口
因此:
clinetX是相对于浏览器的X轴。
offsetX,假如在用户区域点击,如这里的“拖动我”DIV中,它是相对用户区域的X轴,如果在用户区外点击,值与clientX相同。
screenX相对于计算机显示器的X轴。