js 獲取鼠標位置

在 JavaScript 中,當事件發生時,獲取鼠標的位置是件很重要的事件。由於瀏覽器的不兼容性,不同瀏覽器分別在各自事件對象中定義了不同的屬性,說明如下表所示。這些屬性都是以像素值定義了鼠標指針的座標,但是由於它們參照的座標系不同,導致精確計算鼠標的位置比較麻煩。
 

屬性及其兼容性
屬性 說明 兼容性
clientX 以瀏覽器窗口左上頂角爲原點,定位 x 軸座標 所有瀏覽器,不兼容 Safari
clientY 以瀏覽器窗口左上頂角爲原點,定位 y 軸座標 所有瀏覽器,不兼容 Safari
offsetX 以當前事件的目標對象左上頂角爲原點,定位 x 軸座標 所有瀏覽器,不兼容 Mozilla
offsetY 以當前事件的目標對象左上頂角爲原點,定位 y 軸座標 所有瀏覽器,不兼容 Mozilla
pageX 以 document 對象(即文檔窗口)左上頂角爲原點,定位 x 軸座標 所有瀏覽器,不兼容 IE
pageY 以 document 對象(即文檔窗口)左上頂角爲原點,定位 y 軸座標 所有瀏覽器,不兼容 IE
screenX 計算機屏幕左上頂角爲原點,定位 x 軸座標 所有瀏覽器
screenY 計算機屏幕左上頂角爲原點,定位 y 軸座標 所有瀏覽器
layerX 最近的絕對定位的父元素(如果沒有,則爲 document 對象)左上頂角爲元素,定位 x 軸座標 Mozilla 和 Safari
layerY 最近的絕對定位的父元素(如果沒有,則爲 document 對象)左上頂角爲元素,定位 y 軸座標 Mozilla 和 Safari

示例1

下面介紹如何配合使用多種鼠標座標屬性,以實現兼容不同瀏覽器的鼠標定位設計方案。

首先,來看看 screenX 和 screenY 屬性。這兩個屬性獲得了所有瀏覽器的支持,應該說是最優選用屬性,但是它們的座標系時計算機屏幕,也就是說,以計算機屏幕左上角爲定位原點。這對於以瀏覽器窗口爲活動空間的網頁來說沒有任何價值。因爲不同的屏幕分辨率,不同的瀏覽器窗口大小和位置,都使得在網頁中定位鼠標成爲一件很困難的事情。

其次,如果以 document 對象爲座標系,則可以考慮選用 pageX 和 pageY 屬性實現在瀏覽器窗口中進行定位。這對於設計鼠標跟隨來說是一個好主意,因爲跟隨元素一般都以絕對定位的方式在瀏覽器窗口中移動,在 mousemove 事件處理函數中把 pageX 和 pageY 屬性值傳遞給跟絕對定位元素的 top 和 left樣式屬性即可。

IE 事件模型不支持上面的屬性,爲此還需尋求兼容 IE 的方法。而看 clientX 和 clientY 屬性是以 window 對象爲座標系,且 IE 事件模型支持它們,可以選用它們。不過考慮 window 等對象可能出現的滾動條偏移量,所以還應加上相對於 window 對象的頁面滾動的偏移量。


 
  1. var posX = 0, posY = 0;
  2. var event = event || window.event;
  3. if (event.pageX || event.pageY) {
  4. posX = event.pageX;
  5. posY = event.pageY;
  6. } else if (event.clientX || event.clientY) {
  7. posX = event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
  8. posY = event.clientY + document.documentElement.scrollTop + document.body.scrollTop;
  9. }

在上面代碼中,先檢測 pageX 和 pageY 屬性是否存在,如果存在則獲取它們的值;如果不存在,則檢測並獲取 clientX 和 clientY 屬性值,然後加上 document.documentElement 和 document.body 對象的 scrollLeft 和 scrollTop 屬性值,這樣在不同瀏覽器中就獲得了相同的座標值。

示例2

封裝鼠標定位代碼。設計思路:能夠根據傳遞的具體對象,以及相對鼠標指針的偏移量,命令該對象能夠跟隨水保移動。

先定義一個封裝函數,設計函數傳入參數爲對象引用指針、相對鼠標指針的偏移距離,以及事件對象。然後封裝函數能夠根據事件對象獲取鼠標的座標值,並設置該對象爲絕對定位,絕對定位的值爲鼠標指針當前的座標值。

封裝代碼如下:


 
  1. var pos = function (o, x, y, event) { //鼠標定位賦值函數
  2. var posX = 0, posY = 0; //臨時變量值
  3. var e = event || window.event; //標準化事件對象
  4. if (e.pageX || e.pageY) { //獲取鼠標指針的當前座標值
  5. posX = e.pageX;
  6. posY = e.pageY;
  7. } else if (e.clientX || e.clientY) {
  8. posX = event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
  9. posY = event.clientY + document.documentElement.scrollTop + document.body.scrollTop;
  10. }
  11. o.style.position = "absolute"; //定義當前對象爲絕對定位
  12. o.style.top = (posY + y) + "px"; //用鼠標指針的y軸座標和傳入偏移值設置對象y軸座標
  13. o.style.left = (posX + x) + "px"; //用鼠標指針的x軸座標和傳入偏移值設置對象x軸座標
  14. }

下面測試封裝代碼。爲 document 對象註冊鼠標移動事件處理函數,並傳入鼠標定位封裝函數,傳入的對象爲 <div> 元素,設置其位置向鼠標指針右下方偏移(10,20)的距離。考慮到 DOM 事件模型通過參數形式傳遞事件對象,所以不要忘記在調用函數中還要傳遞事件對象。


 
  1. <div id="div1">鼠標追隨</div>
  2. <script>
  3. var div1 = document.getElementById("div1");
  4. document.onmousemove = function (event) {
  5. pos (div1, 10, 20, event);
  6. }
  7. </script>

示例3

獲取鼠標指針在元素內的座標。使用 offsetX 和 offsetY 屬性可以實現這樣的目標,但是 Mozilla 瀏覽器不支持。可以選用 layerX 和 layerY 屬性來兼容 Mozilla 瀏覽器。

設計代碼如下:


 
  1. var event = event || window.event;
  2. if (event.offsetX || event.offsetY) { //適用非Mozilla瀏覽器
  3. x = event.offsetX;
  4. y = event.offsetY;
  5. } else if (event.layerX || event.layerY) { //兼容Mozilla瀏覽器
  6. x = event.layerX;
  7. y = event.layerY;
  8. }

但是,layerX 和 layerY 屬性是以絕對定位的父元素爲參照物,而不是元素自身。如果沒有絕對定位的父元素,則會以 document 對象爲參照物。爲此,可以通過腳本動態添加或者手動添加的方式,設計在元素的外層包圍一個絕對定位的父元素,這樣可以解決瀏覽器兼容問題。考慮到元素之間的距離所造成的誤差,可以適當減去 1 個或幾個像素的偏移量。

完整設計代碼如下:

純文本複製

 
  1. <input type="text" id="text" />
  2. <span style="position:absolute;">
  3. <div id="div1" style="width:200px;height:160px;border:solid 1px red;">鼠標跟隨</div>
  4. </span>
  5. <script>
  6. var t = document.getElementById("text");
  7. var div1 = document.getElementById("div1");
  8. div1.onmousemove = function (event) {
  9. var event = event || window.event; //標準化事件對象
  10. if (event.offsetX || event.offsetY) {
  11. t.value = event.offsetX + "" + event.offsetY;
  12. } else if (event.layerX || event.layerY) {
  13. t.value = (event.layerX-1) + "" + (event.layerY-1);
  14. }
  15. }
  16. </script>

這種做法能夠解決在元素內部定位鼠標指針的問題。但是,由於在元素外面包裹了一個絕對定位的元素,會破壞整個頁面的結構佈局。在確保這種人爲方式不會導致結構佈局混亂的前提下,可以考慮選用這種方法。

發佈了45 篇原創文章 · 獲贊 23 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章