zoukankan      html  css  js  c++  java
  • 网页元素坐标表示及坐标计算方法

    一、页面元素坐标种类

        根据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

  • 相关阅读:
    Python元类
    Python接口与归一化设计
    如何使用yum下载rpm包
    浅谈Python的with语句
    搞懂了这几点,你就学会了Web编程
    网络虚拟化技术大观
    Python装饰器
    Kubernetes配置Ceph RBD StorageClass
    编译Kubelet二进制文件
    记一次虚拟机无法挂载volume的怪异问题排查
  • 原文地址:https://www.cnblogs.com/soundcode/p/13976954.html
Copyright © 2011-2022 走看看