事件位置与offset+client+scroll三大家族

443 阅读3分钟

引言

前端页面存在许多视口,这些繁琐的api很容易导致我们无法区分视口的正确使用,通过本节你将完美区分各类页面视口。

一:事件触发位置

1.1 offsetX/offsetY

offsetX与offsetY的位置是相对于元素本身的偏移量,值得注意的从自身的padding位置开始计算。

//html
<div class="box"></div>

//css
.box{
      border:20px solid red;
      padding: 20px;
      width: 50px;
      height: 50px;
      background: blue;
      margin: 20px auto;
   }
  
  
  //js
  let oBox = document.querySelector(".box");
  oBox.addEventListener('click',(e)=>{
    console.log(e.offsetX,e.offsetY)
  })

1.gif

可以清晰的看到,红色部分属于border,它不是offset偏移的开始位置所以我们点击红色部分是负数。蓝色部分是padding+content内容,padding属于偏移的开始位置,所以点击后偏移量是正数。

1.2 clientX/clientY

client系列是事件触发后相对于当前页面视口的偏移量。

如何区分页面偏移量与页面视口偏移量?

页面偏移量:相对于页面最顶部的偏移量称为页面偏移量。

页面视口偏移量:始终相对于页面可视区最顶部的偏移量。

2.gif

我们将页面滚动到指定位置后,点击盒子可以看到其client偏移量是相对于其当前视口产生,而不是相对于页面偏移量。

1.3 pageX/pageY

page系列的偏移量是相对于页面的偏移量(包括了滚动出去的范围)

3.gif

1.4 screenX/screenY

screen系列是点击位置相对于显示器左上角的偏移量,此api用处不多,且十分容易理解。

二:元素自身属性

2.1 e.style.xxx

e.style可以读取和设置元素的css属性。

读取

  1. 读取时需要注意,style只能读取内联样式,如果是外联的无法读取到。

  2. style.width获取的是内容width,不包括padding与border等

     //html
     <div class="box"></div>
     //css
     .box{
         width: 100px;
         height: 100px;
         background: red;
         padding: 50px;
         border: 50px solid gold;
         margin-top: 900px;
     }
     //js
     let oBox = document.querySelector(".box");
     console.log(oBox.style.width);//空
    

设置

let oBox = document.querySelector(".box");
oBox.style.width='1000px';

2.2 offsetWidth/offsetHeight

offsetWidth/offsetHeight表示元素的宽高。

读取 只能读,无法修改

  • offsetWidth = width+padding+border

  • offsetHeight = height+padding+border

          //html
          <div class="box"></div>
          //css
          .box{
              width: 100px;
              height: 100px;
              background: red;
              padding: 50px;
              border: 50px solid gold;
              margin-top: 900px;
          }
          //js
          let oBox = document.querySelector(".box");
          console.log(oBox.offsetWidth)//100+100+100=300
    

2.3 offsetLeft/offsetTop

offsetLeft/offsetTop:当前元素距离第一个父亲定位元素的水平/垂直偏移量,如果其父亲元素都不是定位元素,则指向body.

读取 offsetLeft/offsetTop只能读取,无法设置。

html

<div class="box">
    <div class="father">
        <div class="son"></div>
    </div>
</div>

css

.box{

    width: 300px;

    height: 300px;

    background: blue;

    position: relative;

 }

   .father{

        width: 200px;

        height: 200px;

        margin-left: 10px;

        background: gold;

    }

    .son{

        width: 100px;

        height: 100px;

        margin-left: 10px;

        background: red;

    }

js

let oBox = document.querySelector(".son");
console.log(oBox.offsetLeft,oBox.offsetTop);//20 0
43.png

可以看到红色盒子距离第一个父元素黄色盒子左侧偏移量是10,距离最外层蓝色盒子的左侧偏移量是20。由于蓝色盒子是定位的,所以其左侧偏移量是20,顶部偏移量是0

2.4 window.getComputedStyle(e)

  1. 获取元素的任意css属性,相对于style的属性获取,该方式不受内联与外联的影响。

  2. 获取的width是元素的内容,不包括padding与border

2.5 e.getBoundingClientRect()

  1. 获取元素宽高:content+padding+border
  2. 获取元素相对于视口的偏移量

2.6 clientWidth/clientHeight

获取元素宽高:content+padding

2.7 clientLeft/clientTop

获取元素宽高:border

2.8 scrollWidth/scrollHeight

scrollWidth/scrollHeight并不是随滚动条滚动而变化,它只根据盒子内容宽高而改变。

元素内容<盒子width

scrollWidth = width+padding

元素内容>盒子width

scrollWidth = width+padding+元素内容超出width部分

2.9 scrollLeft/scrollTop

scrollLeft/scrollTop作用是根据滚动条判断滚动出去的位置

  1. scrollLeft相对于盒子从padding边缘滚动出去的水平方向

  2. scrollTop相对于盒子从padding边缘滚动出去的垂直方向