offset、client、scroll三大家族

目录

一、元素偏移量offset系列

offset概述

 offset 与 style 的区别

案例:获取鼠标在盒子内的坐标

案例:模态框拖拽

案例:仿京东放大镜

二、元素可视区client系列

client概述

 分析flexible.js

三、元素滚动scroll系列

scroll概述

页面被卷去的头部

四、三大系列总结


一、元素偏移量offset系列

offset概述

        offset翻译过来就是偏移量,使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等

(1)获得元素距离带有定位父元素的位置。

(2)获得元素自身的大小(宽度高度)。

(3)注意:返回的数值都不带单位。

offset系列属性作用
element.offsetParent返回作为该元素带有定位的父级元素,如果父级没有定位则返回body
element.offsetTop返回元素相对带有定位父元素上方的偏移
element.offsetLeft返回元素相对带有定位父元素左边框的偏移
element.offsetWidth返回自身包括padding、边框、内容区的宽度。返回数值不带单位
element.offsetHeight返回自身包括padding、边框、内容区的高度。返回数值不带单位

 offset 与 style 的区别

offsetstyle
(1) offset可以得到任意样式表中的样式值(1) style只能得到行内样式表中的样式值
(2) offset系列获得的数值是没有单位的(2) style.width 获得的是带有单位的字符串
(3) offsetWidth包含padding + border + width(3) style.width 获得不包含padding 和 border的值
(4) offsetWidth等属性是只读属性,只能获取不能赋值(4) style.width 是可读写属性,可以获取也可以赋值

所以:获取用offset,修改用style。

  <style>
    * {
      /* margin: 0; */
    }

    .box {
      width: 150px;
      height: 150px;
      background-color: pink;
    }

    .con {
      position: absolute;
      padding: 15px;
    }
  </style>
<body>
  <div class="con">
    <div class="box">

    </div>
  </div>

  <script>
    var box = document.querySelector('.box');
    // offsetLeft、Top、width、height要求父元素带有定位,没有定位父元素返回距离body的距离
    console.log(box.offsetLeft); // 返回左方距离 15
    console.log(box.offsetTop); // 返回上方距离 15
    console.log(box.offsetWidth); // 返回实际宽度 150
    console.log(box.offsetHeight); // 返回实际高度 150
    console.log(box.offsetParent); // 返回定位父元素,没有定位父元素返回body div.con
  </script>
</body>

案例:获取鼠标在盒子内的坐标

  <style>
    .box {
      width: 150px;
      height: 150px;
      background-color: pink;
      font-size: 14px;
      text-align: center;
    }
  </style>
<body>
  <div class="box">

  </div>
  <script>
    /**
     * 1、需要获取盒子
     * 2、需要用到鼠标移动事件 onmousemove
     * 3、鼠标在盒子的位置 = 鼠标距离页面的距离 - 盒子距离body的距离;
     * 4、鼠标距离文档页面的距离需要用到事件对象e,属性:e.pageX、e.pageY
     * 5、盒子距离body的距离,offsetTop、offsetLeft
    */
    var box = document.querySelector('.box');
    box.onmousemove = function (e) {
      var x = e.pageX - this.offsetLeft; // X坐标
      var y = e.pageY - this.offsetTop; // Y坐标
      this.innerHTML = 'X坐标:' + x + ' Y坐标:' + y;
    }
  </script>
</body>

效果:

案例:模态框拖拽

  <style>
    .login-header {
      width: 100%;
      text-align: center;
      height: 30px;
      font-size: 24px;
      line-height: 30px;
    }

    ul,
    li,
    ol,
    dl,
    dt,
    dd,
    div,
    p,
    span,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    a {
      padding: 0px;
      margin: 0px;
    }

    .login {
      display: none;
      width: 512px;
      height: 280px;
      position: fixed;
      border: #ebebeb solid 1px;
      left: 50%;
      top: 50%;
      background: #ffffff;
      box-shadow: 0px 0px 20px #ddd;
      z-index: 9999;
      transform: translate(-50%, -50%);
    }

    .login-title {
      width: 100%;
      margin: 10px 0px 0px 0px;
      text-align: center;
      line-height: 40px;
      height: 40px;
      font-size: 18px;
      position: relative;
      cursor: move;
    }

    .login-input-content {
      margin-top: 20px;
    }

    .login-button {
      width: 50%;
      margin: 30px auto 0px auto;
      line-height: 40px;
      font-size: 14px;
      border: #ebebeb 1px solid;
      text-align: center;
    }

    .login-bg {
      display: none;
      width: 100%;
      height: 100%;
      position: fixed;
      top: 0px;
      left: 0px;
      background: rgba(0, 0, 0, .3);
    }

    a {
      text-decoration: none;
      color: #000000;
    }

    .login-button a {
      display: block;
    }

    .login-input input.list-input {
      float: left;
      line-height: 35px;
      height: 35px;
      width: 350px;
      border: #ebebeb 1px solid;
      text-indent: 5px;
    }

    .login-input {
      overflow: hidden;
      margin: 0px 0px 20px 0px;
    }

    .login-input label {
      float: left;
      width: 90px;
      padding-right: 10px;
      text-align: right;
      line-height: 35px;
      height: 35px;
      font-size: 14px;
    }

    .login-title span {
      position: absolute;
      font-size: 12px;
      right: -20px;
      top: -30px;
      background: #ffffff;
      border: #ebebeb solid 1px;
      width: 40px;
      height: 40px;
      border-radius: 20px;
    }
  </style>
<body>
  <div class="login-header"><a id="link" href="javascript:;">点击,弹出登录框</a></div>
  <div id="login" class="login">
    <div id="title" class="login-title">登录会员
      <span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
    </div>
    <div class="login-input-content">
      <div class="login-input">
        <label>用户名:</label>
        <input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
      </div>
      <div class="login-input">
        <label>登录密码:</label>
        <input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
      </div>
    </div>
    <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
  </div>
  <!-- 遮盖层 -->
  <div id="bg" class="login-bg"></div>
  <script>
    /**
     * 案例分析:
     *  1. 点击弹出层, 模态框和遮挡层就会显示出来 display:block;
        2. 点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none;
        3. 在页面中拖拽的原理:鼠标按下并且移动, 之后松开鼠标
        4. 触发事件是鼠标按下mousedown,鼠标移动mousemove 鼠标松开 mouseup
        5. 拖拽过程:  鼠标移动过程中,获得最新的值赋值给模态框的left和top值,这样模态框可以跟着鼠标走了
        6. 鼠标按下触发的事件源是最上面一行,就是  id 为 title 
        7. 鼠标的坐标减去 鼠标在盒子内的坐标, 才是模态框真正的位置。
        8. 鼠标按下,我们要得到鼠标在盒子的坐标。
        9. 鼠标移动,就让模态框的坐标  设置为  :鼠标坐标 减去盒子坐标即可,注意移动事件写到按下事件里面。
        10. 鼠标松开,就停止拖拽,就是可以让鼠标移动事件解除  
    */
    // 1、点击弹出层, 模态框和遮挡层就会显示出来 display:block;
    var link = document.querySelector('#link');
    var bg = document.querySelector('#bg');
    var login = document.querySelector('#login')
    link.onclick = function () {
      bg.style.display = 'block';
      login.style.display = 'block';
    }

    // 2、点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none;
    var cloneBtn = document.querySelector('#closeBtn');
    cloneBtn.onclick = function () {
      bg.style.display = 'none';
      login.style.display = 'none';
    }
    // 
    var title = document.querySelector('#title')
    // (1) 点击
    title.onmousedown = function (e) {
      // 鼠标在盒子内的坐标
      var x = e.pageX - login.offsetLeft;
      var y = e.pageY - login.offsetTop;
      // (2) 开始拖动
      document.addEventListener('mousemove', move);
      function move(e) {
        // login盒子的left、top值 = 鼠标距离页面文档的距离 - 鼠标在盒子的距离
        login.style.left = e.pageX - x + 'px';
        login.style.top = e.pageY - y + 'px';
      }
      // (3) 松开鼠标时,删除监听器
      document.addEventListener('mouseup', function () {
        document.removeEventListener('mousemove', move);
      })
    }

  </script>
</body>

效果:

案例:仿京东放大镜

  <style>
    .move-box {
      position: relative;
      width: 300px;
      height: 400px;
      border: 1px solid #000;
    }

    .move-box img {
      width: 100%;
    }

    .big {
      display: none;
      position: fixed;
      top: 0;
      left: 50%;
      transform: translateX(-50%);
      width: 400px;
      height: 500px;
      overflow: hidden;
      border: 1px solid #000;
    }

    .pink-box {
      cursor: move;
      display: none;
      position: absolute;
      top: 0;
      left: 0;
      width: 100px;
      height: 100px;
      background-color: pink;
      opacity: .5;
    }

    #bigImg {
      position: fixed;
      top: 0;
      left: 0;
    }
  </style>
<body>
  <div>
    <div class="move-box">
      <img src="./images/b3.png" alt="">
      <div class="pink-box"></div>
    </div>
    <div class="big">
      <img src="./images/big.jpg" alt="" id="bigImg">
    </div>
  </div>
  <script>
    // 1、当鼠标进入小盒子,显示pink盒子、大盒子
    var small = document.querySelector('.move-box');
    var pinkBox = document.querySelector('.pink-box');
    var big = document.querySelector('.big');

    small.addEventListener('mouseover', function () {
      pinkBox.style.display = 'block';
      big.style.display = 'block';
    })
    // 2、当鼠标离开时,隐藏pink盒子、大盒子
    small.addEventListener('mouseout', function () {
      pinkBox.style.display = 'none';
      big.style.display = 'none';
    });

    small.addEventListener('mousemove', function (e) {
      // (1) 鼠标在盒子内的坐标
      var x = e.pageX - small.offsetLeft;
      var y = e.pageY - small.offsetTop;

      // pink盒子的移动距离
      var pinkX = x - pinkBox.offsetWidth / 2;
      var pinkY = y - pinkBox.offsetHeight / 2;

      // 最大移动距离 小盒子 - pink盒子
      var pinkMaxX = small.offsetWidth - pinkBox.offsetWidth;
      var pinkMaxY = small.offsetHeight - pinkBox.offsetHeight;
      // 如果小于0,就停在0的位置
      if (pinkX <= 0) {
        pinkX = 0;
      } else if (pinkX >= pinkMaxX) {
        pinkX = pinkMaxX;
      }
      // 如果小于0,就停在0的位置
      if (pinkY <= 0) {
        pinkY = 0;
      } else if (pinkY >= pinkMaxY) {
        pinkY = pinkMaxY;
      }

      pinkBox.style.left = pinkX + 'px';
      pinkBox.style.top = pinkY + 'px';


      var bigImg = document.querySelector('#bigImg');
      var bigMax = bigImg.offsetWidth - big.offsetWidth;
      // 大图片的移动距离 = 最大移动距离 * 大图片移动距离 / pink盒子最大移动距离
      var bigX = pinkX * bigMax / pinkMaxX;
      var bigY = pinkY * bigMax / pinkMaxY;

      bigImg.style.left = -bigX + 'px';
      bigImg.style.top = -bigY + 'px';
    });

  </script>
</body>

效果:

二、元素可视区client系列

client概述

        cline翻译过来就是客户端,使用clint系列的相关属性来获取元素可视区的相关信息。通过cline系列的相关属性可以动态的得到该元素的边框大小、元素大小等等。

cline系列属性作用
element.clineTop返回元素上边距的大小
element.clineLeft返回元素左边框的大小
element.clineWidth返回自身包括padding、内容区的宽度,不含边框。返回的数值不带单位
element.clineHeight返回自身包括padding、内容区的高度,不含边框。返回的数值不带单位

 分析flexible.js

立即执行函数 (function(){})()  或者 (function(){}())

主要作用: 创建一个独立的作用域。 避免了命名冲突问题

下面三种情况都会刷新页面都会触发 load 事件。

1.a标签的超链接

2.F5或者刷新按钮(强制刷新)

3.前进后退按钮

但是 火狐中,有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了DOM和JavaScript的状态;实际上是将整个页面都保存在了内存里。

所以此时后退按钮不能刷新页面。

此时可以使用 pageshow事件来触发。,这个事件在页面显示时触发,无论页面是否来自缓存。在重新加载页面中,pageshow会在load事件触发后触发;根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件。

注意:这个事件给window添加

;(function flexible(window, document) {
  // 获取的html 的根元素
  var docEl = document.documentElement
  // dpr 物理像素比
  var dpr = window.devicePixelRatio || 1

  // adjust body font size  设置我们body 的字体大小
  function setBodyFontSize() {
    // 如果页面中有body 这个元素 就设置body的字体大小
    if (document.body) {
      document.body.style.fontSize = 12 * dpr + 'px'
    } else {
      // 如果页面中没有body 这个元素,则等着 我们页面主要的DOM元素加载完毕再去设置body
      // 的字体大小
      document.addEventListener('DOMContentLoaded', setBodyFontSize)
    }
  }
  setBodyFontSize()

  // set 1rem = viewWidth / 10    设置我们html 元素的文字大小
  function setRemUnit() {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  }

  setRemUnit()

  // reset rem unit on page resize  当我们页面尺寸大小发生变化的时候,要重新设置下rem 的大小
  window.addEventListener('resize', setRemUnit)
  // pageshow 是我们重新加载页面触发的事件
  window.addEventListener('pageshow', function (e) {
    // e.persisted 返回的是true 就是说如果这个页面是从缓存取过来的页面,也需要从新计算一下rem 的大小
    if (e.persisted) {
      setRemUnit()
    }
  })

  // detect 0.5px supports  有些移动端的浏览器不支持0.5像素的写法
  if (dpr >= 2) {
    var fakeBody = document.createElement('body')
    var testElement = document.createElement('div')
    testElement.style.border = '.5px solid transparent'
    fakeBody.appendChild(testElement)
    docEl.appendChild(fakeBody)
    if (testElement.offsetHeight === 1) {
      docEl.classList.add('hairlines')
    }
    docEl.removeChild(fakeBody)
  }
})(window, document)

三、元素滚动scroll系列

scroll概述

        scroll翻译过来就是滚动的,使用scroll 系列相关属性可以动态的得到该元素的大小、滚动距离等等。

scroll系列属性作用
element.scrollTop返回被卷去的上侧距离。返回数值不带单位
element.scrollLeft返回被卷去的左侧距离。返回数值不带单位
element.scrollWidth返回自身实际的宽度,不含边框。返回数值不带单位
element.scrollHeight返回自身实际的高度,不含边框。返回数值不带单位

页面被卷去的头部

        如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发 onscroll事件

四、三大系列总结

三大系列大小对比作用
element.offsetWidth返回自身包括padding、边框、内容区的宽度。返回数值不带单位
element.clientWidth返回自身包括padding、内容区的宽度,不含边框。返回数值不带单位
element.scrollWidth返回自身实际的宽度,不含边框。返回数值不带单位

它们的主要用法:

(1)offset系列经常用于获得元素位置 offsetTop、offsetLeft

(2)client系列经常用于获取元素大小 clientWidth、clientHeight

(3)scroll系列经常用于获取滚动距离 scrollTop、scrollLeft

(4)注意:页面滚动的距离通过 window.pageXOffset 获得

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值