【前端 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;
    }
<div class="box"></div>
    // 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指的是:文档定义类型即文档首部的 <!DOCTYPE html>
  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;
    }
<div class="father">
  <div class="son"></div>
</div>
 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;
    }
<div></div>
<button>span走起</button>
<span></span>
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 是一门动态语言,可以很方便的给当前对象添加属性。

解决点击次数越多盒子跑得越快的问题和不同元素记录不同的定时器
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容