测试浏览器的版本:
IETester 6 ,7
IE 8.0
Firefox 3.5.5
Chrome 4.1.249.1064 (45376)
Opera 9.64
Safari 4.0
先来看看各个主流浏览器都有哪些坐标属性以及它们的意义
在IE中
event.offsetX
event.offsetY
相对于e.srcElement坐标
设置或获取鼠标指针位置相对于触发事件的对象的 x 坐标。
设置或获取鼠标指针位置相对于触发事件的对象的 y 坐标。
event.clientX
event.clientY
总是相对于视口
设置或获取鼠标指针位置相对于窗口客户区域的 x 坐标,其中客户区域不包括窗口自身的控件和滚动条。
设置或获取鼠标指针位置相对于窗口客户区域的 y 坐标,其中客户区域不包括窗口自身的控件和滚动条。
event.x
event.y
虽然手册上说是相对于文档,但是ie6/7 中,他们俩的值跟clientX,clientY一致
但是这并不是严重的问题,因为视口相对坐标加上滚动条已卷去高度,依然可以得到真实的x(y),这个问题在ie8的标准模式下被解决
设置或获取鼠标指针位置相对于父文档的 x 像素坐标。
设置或获取鼠标指针位置相对于父文档的 y 像素坐标。
event.screenX
event.screenY
设置或获取获取鼠标指针位置相对于用户屏幕的 x 坐标。
设置或获取获取鼠标指针位置相对于用户屏幕的 y 坐标。
在FireFox中
event.layerX
event.layerY
相对于e.srcElement坐标
设置或获取鼠标指针位置相对于触发事件的对象的 x 坐标。
设置或获取鼠标指针位置相对于触发事件的对象的 y 坐标。
event.clientX
event.clientY
总是相对于视口
设置或获取鼠标指针位置相对于窗口客户区域的 x 坐标,其中客户区域不包括窗口自身的控件和滚动条。
设置或获取鼠标指针位置相对于窗口客户区域的 y 坐标,其中客户区域不包括窗口自身的控件和滚动条。
event.pageX
event.pageY
设置或获取鼠标指针位置相对于父文档的 x 像素坐标。
设置或获取鼠标指针位置相对于父文档的 y 像素坐标。
event.screenX
event.screenY
设置或获取获取鼠标指针位置相对于用户屏幕的 x 坐标。
设置或获取获取鼠标指针位置相对于用户屏幕的 y 坐标。
实际上IE和Firefox已经囊括了所有的属性,其他的浏览器将这些属性进行了组合,但是意义完全一致
Chrome 和 Safari
Chrome和Safari这哥俩办事儿则灰常周全,它们收录了所有的坐标属性,包括
event.offsetX
event.offsetY
event.layerX
event.layerY
event.clientX
event.clientY
event.x
event.y
event.pageX
event.pageY
注意:Chrome和Safari的event.x event.y 跟IE6 7 的表现一致,它们和event.clientX,event.clientY相等
Opera坚定的走了ie6 7的道路,它拥有
event.offsetX
event.offsetY
event.clientX
event.clientY
event.x
event.y
差点就和ie一模一样,幸好它有pageX,pageY
event.pageX
event.pageY
注意:Chrome和Safari,以及 Opera 的event.x event.y 都跟IE6 7 的表现一致,它们和event.clientX,event.clientY相等,
而在ie8中,event.x,event.y 则等同于 其他浏览器的event.pageX,event.pageY
为啥米layerX和offsetX, x,和pageX会在某些浏览器里重复出现捏?
因为W3C并没有标准化这些属性,DOM3草案里MouseEvent部分沿用了DOM2的定义,只有两对属性
clientX of type long, readonly
The horizontal coordinate at which the event occurred relative to the viewport associated with the event.
clientY of type long, readonly
The vertical coordinate at which the event occurred relative to the viewport associated with the event
screenX of type long, readonly
The horizontal coordinate at which the event occurred relative to the origin of the screen coordinate system.
screenY of type long, readonly
The vertical coordinate at which the event occurred relative to the origin of the screen coordinate system.
这下杯具了,所以支持标准的浏览器们都木有了方向,但是吧,浏览器厂商转念一想,W3C反正也弄不出幺蛾子来,肯定从offsetXY 和 layerXY,
pageXY 和 xy中间挑一个,于是为了迎合标准,就把这两对属性就都放进了浏览器中。
不管怎么样,出了问题总是要解决掉。看到上面的兼容报告,代码雏形也就做好了
我们开始动手写!
getEventCoord
1 var getEventCoord = function( e )
2 {
3 var evt = e||event;
4 var html = document.documentElement; //滚动条在上
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') );
例子

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6
視覺化網頁開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

禪工作室 13.0.1
強大的PHP整合開發環境