網頁元素坐標表示及坐標計算方法


一、頁面元素坐標種類

    根據DOM的鼠標事件(參見https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent),瀏覽器響應鼠標事件時,會上報四類坐標:

1、(pageX,pageY):相對於整個網頁的坐標,因此坐標點可能比實際屏幕尺寸大。該坐標屬於絕對坐標,不隨着頁面滾動而變化,當網頁渲染完畢后,每個元素的page坐標就已固定。

2、(clientX, clientY):相對於當前視圖區域的坐標,如果元素屬於iframe,則是相對於iframe窗口坐標。

3、(offsetX,offsetY):鼠標位置相對於捕獲事件的目標節點的坐標,如果點擊位置沒有元素,則為相對於body元素的坐標。

4、(screenX,screenY):相對於顯示屏幕的坐標。

5、(layerX, layerY):非標准的特性,可能存在兼容性問題。表示鼠標點相對於該布局層頂端和左端的坐標,一般情況下與pageX、pageY相同,屬於該層的絕對坐標。

但上述坐標中,哪些坐標是Web內核計算輸出的,哪些坐標是傳給Web內核的呢?其實,瀏覽器內核的輸入坐標只有兩個:屏幕坐標(screenX、screenY)和視圖坐標(鼠標點相較於瀏覽器視圖窗口的坐標)。其余4類坐標均是計算而來。

 

二、Chromium/Chrome瀏覽器鼠標事件捕獲

Chromium瀏覽器在觸發鼠標(如點擊)事件時,主程序首先獲得鼠標相對於視圖區域(即去除瀏覽器應用頂部條、地址欄、工具欄、底部欄)的坐標(視圖坐標),並在傳給WebKit內核(或Render進程)前計算出該坐標對應的屏幕坐標(即screenX和screenY),將此兩類坐標封裝成WebMouseEvent對象。流程參見RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event)。上述page、client、offset、layer坐標均是在Chromium內核中通過輸入的視圖區域坐標計算生成。

因此,對於點擊某元素而言,瀏覽器視圖窗口坐標是最重要的。

 

三、元素視圖窗口坐標計算方法

元素相對於當前DOM視圖窗口的坐標可通過getBoundingClientRect()計算而得。但當要計算該元素相對於瀏覽器視圖區域的坐標,尤其針對該元素嵌入在某iframe中的情況,則需要利用getBoundingClientRect()迭代計算而成。代碼如下:

  1.  
    var targetObj=document.getElementById('test'); //假設網頁中存在一個id為test的元素
  2.  
     
  3.  
    function calcViewportLocation(obj, winObj) {
  4.  
    var currentWindow = winObj;
  5.  
    var rect = obj.getBoundingClientRect(); //獲取該元素在當前窗口視圖區域的位置
  6.  
    var top = rect.top;
  7.  
    var left = rect.left;
  8.  
    var width = rect.width;
  9.  
    var height = rect.height;
  10.  
     
  11.  
    //若該元素在某iframe中,則計算該frame相較於父窗口的位置,並向上迭代直到主frame。元素的位置坐標需要累加iframe的偏移。
  12.  
    while (currentWindow.frameElement != null) {
  13.  
    var obj1 = currentWindow.frameElement;
  14.  
    currentWindow = currentWindow.parent;
  15.  
    rect = obj1.getBoundingClientRect();
  16.  
    if (rect.top > 0) { top += rect.top; }
  17.  
    if (rect.left > 0) { left += rect.left; }
  18.  
    }
  19.  
    var final_x = Math.round(left);
  20.  
    var final_y = Math.round(top);
  21.  
    return {y:final_y, x:final_x, w:width, h:height};
  22.  
    }
  23.  
     
  24.  
    //將該元素對象及所在window作為參數傳入。
  25.  
    var result = calcViewportLocation(targetObj, window);

將上述腳本注入到目標元素所在DOM上下文中即可。(注意,若所在元素在iframe中,則Chrome類瀏覽器需要設定--disable-web-security --allow-file-access-from-files啟動參數,否則會因跨域問題無法計算iframe尺寸。)

諸如下圖例子(假設要計算子frame中iframeButton2元素的瀏覽器視圖坐標):

 

藍色橫線表示iframeButton2元素坐上角相對於其所在iframe視圖窗口的坐標,數值為X(92,51),只需要targetObj.getBoundingClientRect()即可計算得到。而相對於瀏覽器視圖窗口的坐標則為(380,59),是X加上元素所在iframe的視圖窗口位置所得。

 

轉:https://blog.csdn.net/weixin_42080566/article/details/80105259


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM