时间:2021-07-01 10:21:17 帮助过:2人阅读
1 var getEventCoord = function( e )
2 {
3 var evt = e||event;
4 var html = document.documentElement; //滚动条在<HTML>上
5 return {
6
7 //如果pageX属性为真 就使用pageX,否则就使用 clientX + html.scrollLeft
8 pageX : evt.pageX || evt.clientX + html.scrollLeft,
9
10 //如果pageY属性为真 就使用pageY,否则就使用 clientY + html.scrollTop
11 pageY : evt.pageY || evt.clientY + html.scrollTop,
12
13 //clientX Y 大家都一致,木有悬念
14 clientX : evt.clientX,
15 clientY : evt.clientY,
16
17 //如果layerX属性为真 就使用layerX,否则就使用 offsetX
18 layerX : evt.layerX || evt.offsetX,
19
20 //如果layerY属性为真 就使用layerY,否则就使用 offsetY
21 layerY : evt.layerY || evt.offsetY
22 }
23 }
用法如下
代码如下:
document.onmousemove = function( e )
{
var coord = getEventCoord(e);
document.title = [coord.pageX,coord.pageY];
}
看起来已经灰常的OK,似乎已经能满足日常工作需要了,但还是存在几个问题
1.不严谨
使用 evt.pageX || evt.clientX + html.scrollLeft 这种判断,
只要evt.pageX 等于 undefined,null,NaN,'',0,false 这些值,左边的表达式结果就为false,从而计算右边的表达式并返回表达式的值,
而evt.pageX本身就是有机会返回0的。所以这条判断应该改为
typeof evt.pageX == 'number' ? evt.pageX : evt.clientX + html.scrollLeft
pageX是个数字的时候我们才使用它
2.无法工作在怪异模式中
什么是怪异模式?
IE为了兼容IE56之前版本,在ie6中引入了两种渲染模式: 怪异模式(Quicks Mode) 和 标准模式 (Standards Mode)
两种模式差异主要集中在css的盒模型解释方面,而BOM中。则是滚动条的依赖对象发生了变化
在怪异模式中,滚动条是body的,如果想取得页面的滚动卷去的高度和宽度,需要使用document.body.scrollTop
而标准模式中需要使用document.documentElement.scrollTop
而两种模式的切换方式主要是由doctype来确定,参见:http://dancewithnet.com/2009/06/14/activating-browser-modes-with-doctype/
从ie6开始,ie使用一个属性 document.compatMode 来检测文档是否切换到了怪异模式还是处在标准模式
如果document.compatMode的值
为BackCompat:就是在怪癖模式下
为CSS1Compat:就是在标准模式下
所以这里为了在两个模式中都工作正常,
我们需要判断document.compatMode是哪个模式
而判断的方式也很简单,只需要判断compatMode的值的第一个字母是否为b,就可以选择scrollTop的依赖对象
判断方式可以这么写
document.compatMode.indexOf('b')==0
也可以用正则写
/^b/i.test( document.compatMode )
第二种显得更牛x一点。。嗯,就用第二种(实际上第一种性能好一点)
现在再来写第二版吧
代码
代码如下:
var getEventCoord = function( e )
{
var evt = e||event, d = document,
scrollEl = /^b/i.test( d.compatMode ) ? d.body : d.documentElement,
supportPage = typeof evt.pageX == 'number',
supportLayer = typeof evt.layerX == 'number'
return {
pageX : supportPage ? evt.pageX : evt.clientX + scrollEl.scrollLeft,
pageY : supportPage ? evt.pageY : evt.clientY + scrollEl.scrollTop,
clientX : evt.clientX,
clientY : evt.clientY,
layerX : supportLayer ? evt.layerX : evt.offsetX,
layerY : supportLayer ? evt.layerY : evt.offsetY
}
}
噔噔噔噔,这就搞定了,这个函数能干啥哩,首先想到的就是拖拽,让我们写一个小小的拖拽函数验证一下下
代码
代码如下:
function dragMe( o )
{
var supportCapt = !!o.setCapture;
o.onmousedown = function(e)
{
var coord = getEventCoord(e), x = coord.layerX, y = coord.layerY;
if( supportCapt ) o.setCapture();
document.onmousemove = function(e)
{
var coord = getEventCoord(e);
o.style.left = coord.pageX - x + 'px';
o.style.top = coord.pageY - y + 'px';
}
document.onmouseup = function()
{
this.onmousemove = this.onmouseup = null;
if( supportCapt ) o.releaseCapture();
}
}
}
dragMe( document.getElementById('block') );
例子
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]