js div拖拽实现兼容ie/firefox js之鼠标位置深入解析

在前端web开发中,不可避免地会应用到对某个对象的拖拽操作,尤其经常是一个div层。对页面对象的位置移动操作,难点就在如何准确的获取鼠标位置,本文就对鼠标位置做一些分析对比,最后完成一个对div的拖拽操作。

js中获取鼠标位置的各种参数
名称解释
clientX事件属性返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标。
clientY事件属性返回当事件被触发时鼠标指针向对于浏览器页面(客户区)的垂直坐标。
screenX事件属性可返回事件发生时鼠标指针相对于屏幕的水平坐标。
screenY事件属性可返回事件发生时鼠标指针相对于屏幕的垂直坐标。
offsetX事件发生的地点在事件源元素的坐标系统中的 x 坐标(ie)。
offsetY事件发生的地点在事件源元素的坐标系统中的 y 坐标(ie)。
x事件发生的位置的 x 坐标, 它相对于用CSS动态定位的最内层包容元素(ie,~pageX)。
y事件发生的位置的 y 坐标, 它相对于用CSS动态定位的最内层包容元素(ie,~pageY)。
pageX鼠标指针的位置,相对于文档的左边缘(firefox,~x)。
pageY鼠标指针的位置,相对于文档的上边缘(firefox,~y)。
layerX鼠标相比较于当前坐标系的位置(firefox,~offsetX)。
layerY鼠标相比较于当前坐标系的位置(firefox,~offsetY)。

1、clientX/clientY:

这两个属性分别返回当事件被触发时鼠标指针向对于浏览器页面(客户区)的水平、垂直坐标,如图:

2、screenX/screenY:

返回事件发生时鼠标指针相对于屏幕的水平、垂直坐标,如图:

3、offsetX/offsetY:

这两个属性是IE浏览器特有的,指发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。注意,这里不再是针对整个浏览器或整个屏幕了,而是对于发生事件的对象而言,下面的图例以红色区域作为事件源来展现offsetX、offsetY相对于红色区域左上角的位置坐标:

4、x、y:

这两个属性也是IE特有的,指事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素,也即相对于目标事件的父元素的外边界在xy坐标上的位置。相当于firefox中的pageX、pageY坐标。当事件源的父对象为document时,x和y与clientX、clientY相同。

当目标源的父级不是浏览器窗口时,xy的值将不同于clientX和clientY:

5、layerX/layerY:

鼠标相比较于当前坐标系的位置,该属性是firefox中支持的,相似于IE中的offsetX和offsetY。

 

6、pageX/pageY:

鼠标指针的位置,相对于文档的左边缘和上边缘,是firefox中支持的,相似于ie中的x和y。

6、可拖拽div

根据上面的分析,我们来做一个可拖拽的div,先分析下移动div原理:

如图,如果设鼠标位置1点坐标为(x0,y0),鼠标位置2点为(x1,y1),B点为(x,y),鼠标距离在红色区域的位置为:(left,top),那么:

x = (x0-left) + (x1-x0)=x1-left,y=(y0-top) + (y1-y0)=y1-top.

即B点坐标为(x1-left,y1-top)。

结合鼠标事件,整体思路为:

  • 当鼠标按下时,记录当前的left、top值,如果是ie,即为(offsetX,offsetY),如果是firefox,即为(layerX,layerY)。同时设置可移动标识为true。
  • 当鼠标移动时,如果可移动标识为false,则直接返回,否则获得当前的x,y值,如果是ie,即为(x,y),如果是firefox,即为(pageX,pageY),并设置当前的div坐标为上面B点的坐标值。
  • 当鼠标松开时,设置可移动标记为false。

下面是本文所有截图实现的源代码,供参考:

js脚本:

<script type="text/javascript" src="../script/jquery-1.4.2.min.js"></script>
        <script type="text/javascript">
        	//left,top是按下鼠标时相对于当前事件源的坐标
        	var left=0,top=0;
			var flag = false;
        	$(function(){
				$(document).mousemove(function(evt){
					evt = window.event || evt;
					//位置测试
					//clientX 事件属性返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标。
					//clientY 事件属性返回当事件被触发时鼠标指针向对于浏览器页面(客户区)的垂直坐标。
					var $clientX = evt.clientX;
					var $clientY = evt.clientY
					valueShow('_clientX',$clientX);
					valueShow('_clientY',$clientY);
					
					//screenX 事件属性可返回事件发生时鼠标指针相对于屏幕的水平坐标。
					//screenY 事件属性可返回事件发生时鼠标指针相对于屏幕的垂直坐标。
					var $screenX = evt.screenX;
					var $screenY = evt.screenY;
					valueShow('_screenX',$screenX);
					valueShow('_screenY',$screenY);
				});
				$('#srcdiv').mousemove(function(evt){
					//$console.empty();
					evt = window.event || evt;
					///IE支持的
					//发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。
					var $offsetX = evt.offsetX;
					var $offsetY = evt.offsetY;
					valueShow('_offsetX',$offsetX);
					valueShow('_offsetY',$offsetY);
					//事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。
					var $x = evt.x;
					var $y = evt.y;
					valueShow('_x',$x);
					valueShow('_y',$y);
					//鼠标指针的位置,相对于文档的左边缘和上边缘。
					var $pageX = evt.pageX;
					var $pageY = evt.pageY;
					valueShow('_pageX',$pageX);
					valueShow('_pageY',$pageY);
					
					var $layerX = evt.layerX;
					var $layerY = evt.layerY;
					valueShow('_layerX',$layerX);
					valueShow('_layerY',$layerY);
				});
				$('#abc').mousemove(function(evt){
					evt = window.event || evt;
					///IE支持的
					//事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。
					var $x = evt.x;
					var $y = evt.y;
					valueShow('_x',$x);
					valueShow('_y',$y);
					
					var $pageX = evt.pageX;
					var $pageY = evt.pageY;
					valueShow('_pageX',$pageX);
					valueShow('_pageY',$pageY);
				});
				//console随滚动条浮动
				$(window).scroll(function(){
					var top = document.documentElement.scrollTop;
					$('#console').offset({top:top});
				});
				function valueShow(id,msg){
					$('#'+id).text(msg);
				}
				//------------鼠标拖拽-----------
				$('#srcdiv').mousedown(function(evt){
					flag = true;//鼠标按下
					var isIE = (document.all) ? true : false;
					if(isIE){
						left = event.offsetX;
						top = event.offsetY;
					}else{
						left = evt.layerX;
						top = evt.layerY;
					}
				});
				$('#srcdiv').mousemove(function(evt){
					if(!flag)return;//开始拖动
					var isIE = (document.all) ? true : false;
					var x = isIE?event.x:evt.pageX;
					var y = isIE?event.y:evt.pageY;
					x = (x - left)>0?(x - left):0;
					y = (y - top)>0?(y - top):0;
					$(this).offset({
						left: x  ,
						top: y 
					});
				});
				$(document).mouseup(function(evt){
					flag = false;//鼠标抬起
				});
			});
        </script>

页面:

<div id="console">
    		<table border="1">
    			<tr><td>名称</td><td>解释</td><td>值</td></tr>
    			<tr><td>clientX</td><td>事件属性返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标。</td><td id="_clientX"></td></tr>
    			<tr><td>clientY</td><td>事件属性返回当事件被触发时鼠标指针向对于浏览器页面(客户区)的垂直坐标。</td><td id="_clientY"></td></tr>
    			<tr><td>screenX</td><td>事件属性可返回事件发生时鼠标指针相对于屏幕的水平坐标。</td><td id="_screenX"></td></tr>
    			<tr><td>screenY</td><td>事件属性可返回事件发生时鼠标指针相对于屏幕的垂直坐标。</td><td id="_screenY"></td></tr>
    			<tr><td>offsetX</td><td>事件发生的地点在事件源元素的坐标系统中的 x 坐标(ie)</td><td id="_offsetX"></td></tr>
    			<tr><td>offsetY</td><td>事件发生的地点在事件源元素的坐标系统中的 y 坐标(ie)</td><td id="_offsetY"></td></tr>
    			<tr><td>x</td><td>事件发生的位置的 x 坐标, 它相对于用CSS动态定位的最内层包容元素(ie,~pageX)。</td><td id="_x"></td></tr>
    			<tr><td>y</td><td>事件发生的位置的 y 坐标, 它相对于用CSS动态定位的最内层包容元素(ie,~pageY)。</td><td id="_y"></td></tr>
    			<tr><td>layerX</td><td>鼠标相比较于当前坐标系的位置(firefox,~offsetX)</td><td id="_layerX"></td></tr>
    			<tr><td>layerY</td><td>鼠标相比较于当前坐标系的位置(firefox,~offsetY)</td><td id="_layerY"></td></tr>
    			<tr><td>pageX</td><td>鼠标指针的位置,相对于文档的左边缘(firefox,~x)。</td><td id="_pageX"></td></tr>
    			<tr><td>pageY</td><td>鼠标指针的位置,相对于文档的上边缘(firefox,~y)。</td><td id="_pageY"></td></tr>
    		</table>
    	</div>
		<div id="srcdiv" style="background:red;width:200px;height:100px;position:absolute;left:800px;top:200px;text-align:center;line-height:100px;cursor:move;">
			<h3>测试区</h3>
		</div>
        <table border='1' cellspacing='60' style="position:relative;left:300;top:100;float:right;margin:10px;display:none;">
            <tr>
                <td>
                    <div id="abc" style="background:silver;line-height:50px;">
                        内层div 
                    </div>
                </td>
            </tr>
        </table>
		<br><br><br><br><br>

点击获得全部代码
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值