• 获取元素相对浏览器窗口的偏移坐标


    元素坐标:

    • 浏览器坐标系统
    • 使用offsetParent属性获取元素的坐标
    • 使用w3c标准属性elem.getBoundingClientRect获取元素的坐标
    • 结合以上两种方式,实现兼容浏览器的获取坐标方式
    • 摘要

    *在浏览器中存在两个坐标系统:*

    1. 相对文档——坐标远点在页面的左上角
    2. 相对可视化窗口——坐标原点在可视窗口的左上角

    1. 坐标系统

    当页面没有滚动时,窗口和页面共享相同的坐标原点,如下图所示:

    img

    滚动后,页面相对可视窗口发生了偏移如下图:

    img

    事实上,在这两种坐标系统间相互转化很简单,页面坐标是窗口坐标加上页面滚动偏移

    大部分时候,仅仅使用页面坐标,因为他们滚动后维持相同。

    2. 使用offsetParent属性获取元素的坐标

    元素的坐标是元素左上角的坐标,不幸的是没有一个单一的属性可以获取到它的值,但可以是哟个offsetTop/offsetLeft和offsetParent计算它的值。

    img

    一种计算元素的绝对坐标的方式是遍历offsetParent链,并对遍历中的每个定位父元素的offsetLeft/offsetTop求和,如下所示:

    function getOffsetSum(elem) {
      var top=0, left=0
      while(elem) {
        top = top + parseInt(elem.offsetTop)
        left = left + parseInt(elem.offsetLeft)
        elem = elem.offsetParent       
      }
      return {top: top, left: left}
    }
    

    但这种方式有两个缺陷:

      1. 它存在bug,不同的浏览器存在不同的问题,当考虑边框和滚动的时候会出现问题。

      2. 它计算起来很慢,每次都要遍历整个offsetParents链

    可以写一个跨浏览器修复bug的方法,但先让我们来看另外一种标准做法,该方法在IE6+,firefox3+ OPera ,和safrari及chrome中也支持

    3. 正确的方式:elem.getBoundingClientRect

    这个方式在W3C标准下有描述,大多数现代浏览器都支持,包括IE

    它返回一个包裹元素的矩形框,这个矩形框以top , left , right , bottom四个属性给出。

    这四个数字代表了矩形的左上角和右下角的四个坐标,例如:

    <input id="brTest" type="button" value="Show button.getBoundingClientRect()" onclick='showRect(this)'/>
    
    <script>
    function showRect(elem) {
      var r = elem.getBoundingClientRect()
      alert("Top/Left: "+r.top+" / "+r.left)
      alert("Right/Bottom: "+r.right+" / "+r.bottom)
    }
    </script>
    

    这个坐标是相对窗口,而不是相对文档。

    让我们来看一个新版本的计算坐标的方式:使用getBoundingClientRect

    function getOffsetRect(elem) {
        var box = elem.getBoundingClientRect()
        var body = document.body
        var docElem = document.documentElement
        var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop
        var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft
        var clientTop = docElem.clientTop || body.clientTop || 0
        var clientLeft = docElem.clientLeft || body.clientLeft || 0
        var top  = box.top +  scrollTop - clientTop
        var left = box.left + scrollLeft - clientLeft
        return { top: Math.round(top), left: Math.round(left) }
    }
    

    计算步骤如下:

    1. 获取到包含的矩形框
    2. 计算页面的滚动,除了IE<9外,所有浏览器都支持pageXOffset / pageYOffset,在IE中,当设置了DOCTYPE时,滚动的值可以通过documentElement获得,否则使用body对象获取。
    3. 在IE中文档会相对左上角偏移几个像素,需要去掉它,减去clientTop和clientLeft
    4. 矩形框的坐标加上页面相对窗口滚动的坐标,减去偏移的坐标,就得到了元素相对整个文档的坐标。

    4. 跨浏览器兼容的解决方案:

    有很多js库结合两种方式,获取元素的坐标:

    function getOffset(elem) {
        if (elem.getBoundingClientRect) {
            return getOffsetRect(elem)
        } else { // old browser
            return getOffsetSum(elem)
        }
    }
    
  • 相关阅读:
    linux系统判断内存是否达到瓶颈的小技巧
    利用tcpdump命令统计http的GET和POST请求
    tcpdump 基于mac地址抓取数据包
    使用liunx系统自带的工具sar监控指定接口速率
    Windows 环境搭建Redis集群
    Windows下RabbitMQ安装,部署,配置
    鼠标事件(二)
    鼠标事件(一)
    响应式web之媒体查询(一)
    UI事件之unload、resize和scroll
  • 原文地址:https://www.cnblogs.com/zyyhxbs/p/12376181.html
Copyright © 2020-2023  润新知