【前端 JavaScript WebAPI】05 - PC端网页特效

1. 元素偏移量 offset 系列

1.1 offset 概述

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

  1. 获得元素距离带有定位父元素的位置;

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

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

offset系列属性
offset

1.2 offset 与 style 区别

offset
  1. offset可以得到任意样式表中的样式值;

  2. offset 系列获得的数值是没有单位的;

  3. offsetWidth 包含 padding+border+width ;

  4. offsetWidth 等属性是只读属性,只能获取不能赋值;

  5. 所以,我们想要获取元素大小位置,用offset更合适。

style
  1. style 只能得到行内样式表中的样式值;

  2. style.width 获得的是带有单位的字符串;

  3. style.width 获得不包含paddingborder 的值;

  4. style.width 是可读写属性,可以获取也可以赋值;

  5. 所以,我们想要给元素更改值,则需要用style改变;

  6. 因为平时我们都是给元素注册触摸事件,所以重点记住 targetTocuhes

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

  1. 我们在盒子内点击,想要得到鼠标距离盒子左右的距离。

  2. 首先得到鼠标在页面中的坐标(e.pageX, e.pageY)。

  3. 其次得到盒子在页面中的距离 (box.offsetLeft,box.offsetTop)。

  4. 用鼠标距离页面的坐标减去盒子在页面中的距离,得到 鼠标在盒子内的坐标。

  5. 如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动。

.box {
      width: 300px;
      height: 300px;
      margin: 200px;
      background-color: skyblue;
    }
    // 1. 首先获取到鼠标在页面中的坐标距离 body ,之后获取到盒子距离页面的距离 box 。 通过 body - box 可得到鼠标距离盒子的距离
    let box = document.querySelector('.box');
    box.addEventListener('mouseover', function (e) {
    let pageX = e.pageX;
    let pageY = e.pageY;

    let offsetLeft = this.offsetLeft;
    let offsetTop = this.offsetTop;

    let x = (pageX - offsetLeft);
    let y = (pageY - offsetTop);
    this.innerHTML = 'x坐标 : ' + x + 'y坐标 : ' + y;
  });

1.4 案例:模态框拖拽

  1. 【前端案例】15 - 案例:模态框拖拽 - 。

1.5 案例:图片放大器

3. 元素可视区 client 系列

2.1 client概述

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

2.2 淘宝 flexible.js 源码分析

立即执行函数
  1. 立即执行函数不需要调用立马能够执行。

  2. 普通函数:

function fn() {
    console.log('我是函数');
  }

  fn();
  1. 立即执行函数:
 // 2. 立即执行函数写法
  (function (a, b, c) {
    console.log(a + b + c);
    // 在立即函数中定义的变量是局部变量,不会有冲突问题
  })(1, 2, 3); // 第二个小括号可以看做是调用函数

  // 如果有多个立即执行函数需要使用 分号分隔开
  // 或者
  (function () {
    console.log('我是立即函数');
  }())
  1. 立即执行函数的主要作用 : 创建一个独立的作用域。 避免了命名冲突问题。
下面三种情况都会刷新页面都会触发 load 事件。
  1. a标签的超链接;

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

  3. 前进后退按钮。

但是 火狐中,有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了 DOMJavaScript 的状态;实际上是将整个页面都保存在了内存里。所以此时后退按钮不能刷新页面。
使用 pageshow 事件解决上面的问题:,这个事件在页面显示时触发,无论页面是否来自缓存。在重新加载页面中,pageshow会在 load 事件触发后触发;根据事件对象中的 persisted 来判断是否是缓存中的页面触发的 pageshow 事件。

注意这个事件给window添加。

3. 元素滚动 scroll 系列

3.1 scroll 概述

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

3.2 页面被卷去的头部

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

3.3 案例:仿淘宝固定右侧侧边栏

  1. 【前端案例】17 - 案例:仿淘宝固定右侧侧边栏 -

3.4 页面被卷去的头部兼容性解决方案

需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:
  1. 声明了 DTD,使用 document.documentElement.scrollTopDTD指的是:文档定义类型即文档首部的
  2. 未声明 DTD,使用 document.body.scrollTop;
  3. 新方法 window.pageYOffsetwindow.pageXOffsetIE9 开始支持。
function getScroll() {
    return {
      left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
      top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
    };
 } 
使用的时候  getScroll().left

4. 三大系列总结

三大系列总结
他们主要用法:
  1. offset系列 经常用于获得元素位置 offsetLeft offsetTop

2.client经常用于获取元素大小 clientWidth clientHeight

  1. scroll 经常用于获取滚动距离 scrollTop scrollLeft

  2. 注意页面滚动的距离通过 window.pageXOffset 获得。

5. mouseentermouseover 的区别

  1. 当鼠标移动到元素上时就会触发 mouseenter 事件;

  2. 类似 mouseover,它们两者之间的差别是;

  3. mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter 只会经过自身盒子触发;

  4. 之所以这样,就是因为 mouseenter 不会冒泡;

  5. mouseenter 搭配鼠标离开 mouseleave同样不会冒泡。

.father {
      position: relative;
      width: 200px;
      height: 200px;
      margin: 100px auto;
      background-color: skyblue;
    }

    .son {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 50px;
      height: 50px;
      background-color: deepskyblue;
    }
 let father = document.querySelector('.father');

  /**
   * 1. mouseenter : --> mouseleave
   *
   * 2. mouseover
   */
  /*father.addEventListener('mouseover', function () {
    console.log('mouseover');
  });*/

  father.addEventListener('mouseenter', function () {
    console.log('mouseenter');
  });

6. 动画函数封装

div {
      position: absolute;
      top: 0;
      left: 0;
      width: 100px;
      height: 100px;
      background-color: skyblue;
    }

    span {
      display: block;
      position: absolute;
      top: 150px;
      left: 0;
      width: 100px;
      height: 100px;
      background-color: deepskyblue;
    }
let div = document.querySelector('div');
  let span = document.querySelector('span');
  let button = document.querySelector('button');


  function animal(element, target, interval) {
    /**
     * element.timer 代替 let timer 可以节省 给不同的元素指定了不同的定时器 使用对象属性的方式存定时器
     * @type {number}
     */
    clearInterval(element.timer)
    element.timer = setInterval(function () {
      if (element.offsetLeft >= target) {
        clearInterval(timer);
      } else {
        element.style.left = element.offsetLeft + 1 + 'px';
      }
    }, interval);
  }

  animal(div, 400, 20);

  /**
   * 当点击的次数越来越多的时候出现跑的很快的bug
   *
   * 解决方案就是让其只有一个定时器执行 ,先清以前的定时器只保留当前的一个定时器执行
   */
  button.addEventListener('click', function () {
    animal(span, 600, 5);
  });

6.1 动画实现原理

核心原理:通过定时器 setInterval() 不断移动盒子位置。

实现步骤:
  1. 获得盒子当前位置;

  2. 让盒子在当前位置加上1个移动距离;

  3. 利用定时器不断重复这个操作;

  4. 加一个结束定时器的条件;

  5. 注意此元素需要添加定位,才能使用element.style.left

6.2 动画函数给不同元素记录不同定时器

  1. 如果多个元素都使用这个动画函数,每次都要 let 声明定时器。我们可以给不同的元素使用不同的定时器(自己专门用自己的定时器)。

核心原理:利用 JS 是一门动态语言,可以很方便的给当前对象添加属性。

解决点击次数越多盒子跑得越快的问题和不同元素记录不同的定时器

你可能感兴趣的:(【前端 JavaScript WebAPI】05 - PC端网页特效)