PC端网页特效

  • 1. 元素偏移量 offset 系列
    • 1.1 offset 概述
    • 1.2 offset 与 style 区别
  • 2. 元素可视区 client 系列
    • 2.1 立即执行函数
    • 2.2 load 事件的触发
  • 3. 元素滚动 scroll 系列
    • 3.1 元素 scroll 系列属性
    • 3.2 页面被卷去的头部
    • 3.3 页面被卷去的头部兼容性解决方案
  • 三大系列总结
  • mouseenter 和mouseover的区别
  • 4. 动画函数封装
    • 4.1 动画实现原理
    • 4.2 动画函数的简单封装
    • 4.3 动画函数给不同元素记录不同定时器
    • 4.4 缓动效果原理
    • 4.5 动画函数多个目标值之间移动
    • 4.6 动画函数添加回调函数
    • 4.7 动画函数封装到单独的JS文件
  • 5. 常见网页特效案例
    • 5.1 案例:网页轮播图(JavaScript原生写法)
    • 5.2 节流阀

1. 元素偏移量 offset 系列

1.1 offset 概述

offset — 偏移量, 使用 offset 系列相关属性可动态的得到该元素的位置(偏移)、大小等。

  • 获得元素距离带有定位父元素的位置;
  • 获得元素自身的大小(宽度高度)。
  • 注: 返回的数值都不带单位

offset 系列常用属性:

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

1.2 offset 与 style 区别

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

因此,
想要获取元素大小位置,用offset更合适;
想要给元素更改值,则需要用style改变。

  • 获得元素距离带有定位父元素的位置;
  • 获得元素自身的大小(宽度高度)。


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

  • 实现思路
    ① 得到鼠标在页面中的坐标(e.pageX, e.pageY
    ② 得到盒子在页面中的距离 ( box.offsetLeft, box.offsetTop)
    ③ 鼠标在页面中的坐标减去盒子在页面中的距离,得到鼠标在盒子内的坐标
    ④ 移动鼠标,获取最新的坐标,使用鼠标移动事件 mousemove

  • 实现代码

var box = document.querySelector('.box');
box.addEventListener('mousemove', function(e) {var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;})

2. 元素可视区 client 系列

client (客户端),利用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

client系列属性 返回值
element.clientTop 返回元素上边框的大小
element.clientLeft 返回元素左边框的大小
element.clientWidth 返回自身,包换padding/内容区的宽度,不含边框,返回数据不带单位
element.clientHeight 返回自身,包换padding/内容区的高度,不含边框,返回数据不带单位

2.1 立即执行函数

  • 立即执行函数不需要调用,立马能够自己执行;
  • 主要作用:创建一个独立的作用域,里面所有的变量都是局部变量,避免了命名冲突问题
  • 立即执行函数的用法
  (function () {})()//或者 (function () {}())
<script>// (function() {})()(function(a,b) {console.log(a + b);})(1, 2)  // 第二个小括号可以看作是调用函数// (function() {}())(function(a,b) {console.log(a + b);}(2,3))
</script>

下面是 淘宝 flexible.js 源码分析

(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 / 10docEl.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))

2.2 load 事件的触发

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

a标签的超链接
F5或者刷新按钮(强制刷新)
前进后退按钮

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

3. 元素滚动 scroll 系列

3.1 元素 scroll 系列属性

scroll 意为滚动,使用 scroll 系列的相关属性可动态获得该元素的大小、滚动距离等。

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

3.2 页面被卷去的头部

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

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

  • 原先侧边栏是绝对定位
  • 当页面滚动到一定位置,侧边栏改为固定定位;
  • 页面继续滚动,会让 返回顶部显示出来。

实现思路

① 页面滚动事件 scroll,事件源:document
② 滚动到某个位置,获取页面被卷去的上部值;
③ 页面被卷去的头部:通过window.pageYOffset获得。(如果是被卷去的左侧,则通过window.pageXOffset获得);
④ 注:元素被卷去的头部是 element.scrollTop ;如果是页面被卷去的头部则是 window.pageYOffset
这个值,也可以通过盒子的 offsetTop得到,如果≥这个值,就让盒子变成固定定位.。

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

需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:

  1. 声明了 DTD,使用 document.documentElement.scrollTop
  2. 未声明 DTD,使用 document.body.scrollTop
  3. 新方法 window.pageYOffset 和 window.pageXOffset,IE9 开始支持

兼容性函数封装

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

三大系列总结

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

主要用途/用法

系列 用途、用法
offset系列 经常用于获得元素位置 offsetLeft、offsetTop
client系列 经常用于获取元素大小 clientWidth、 clientHeight
scroll系列 经常用于获取滚动距离 scrollTop 、scrollLeft

页面滚动距离通过 window.pageXOffset 获得

mouseenter 和mouseover的区别

  • mouseenter 鼠标事件
mouseenter mouseover
当鼠标移动到元素上时就会触发
只会经过自身盒子触发(mouseenter不会冒泡) 鼠标经过自身盒子会触发,经过子盒子还会触发。
跟它搭配,mouseleave(鼠标离开) 同样不会冒泡

4. 动画函数封装

4.1 动画实现原理

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

  1. 获得盒子当前位置
  2. 让盒子在当前位置增加或减少1个单位的移动距离;
  3. 利用定时器不断重复这个操作
  4. 加一个结束定时器的条件

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

4.2 动画函数的简单封装

函数需要传递2个参数,动画对象移动到的距离

<div></div>
<span>文化长廊</span>
<script>// obj:目标对象 target:目标位置function animate(obj, target) {var timer = setInterval(function() {if (obj.offsetLeft >= target) {// 停止动画 其实质是停止定时器。clearInterval(timer);}obj.style.left = obj.offsetLeft + 1 + 'px';}, 30);}var div = document.querySelector('div');var span = document.querySelector('span');// 调用函数animate(div, 250);animate(span, 420);
</script>

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

如果多个元素都使用同一动画函数,则无需每次都去声明定时器。可给不同的元素使用不同的定时器
核心原理:由于JavaScript是一门动态语言,所以可以很方便的给当前对象添加属性。

实例代码如下:

<button>点我</button><div></div><span>文化长廊</span><script>// var obj = {};// obj.name = 'Rose';// obj:目标对象;target:目标位置// 给不同的元素指定不同的定时器function animate(obj, target) {// 当连续点击按钮,元素的速度会逐渐加快,原因是开启了多个定时器;// 解决方案:确保只有一个定时器执行;// 清除先前的定时器,只保留执行当前一个定时器,clearInterval(obj.timer);obj.timer = setInterval(function() {if (obj.offsetLeft >= target) {// 停止动画 其实质是停止定时器clearInterval(obj.timer);}obj.style.left = obj.offsetLeft + 1 + 'px';}, 30);}var div = document.querySelector('div');var span = document.querySelector('span');var btn = document.querySelector('button');// 调用函数animate(div, 450);btn.addEventListener('click', function() {animate(span, 250);})</script>

4.4 缓动效果原理

缓动动画:就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
实现思路

  1. 让盒子每次移动的距离慢慢变小;
  2. 核心算法: (目标值 - 现在的位置 ) / 10 做为每次移动的距离 步长
  3. 停止的条件: 当 当前盒子位置 = 目标位置 就停止定时器

注:步长值需要取整。

实例代码(缓动动画函数封装):

// 缓动动画函数封装
<button>点我</button>
<span>文化长廊</span><script>// obj:目标对象;target:目标位置// 1. 让盒子每次移动的距离逐渐变小。// 2. 每次移动的距离(步长):(目标值 - 现在的位置) / 10 // 3. 停止条件: 当前盒子位置 = 目标位置时function animate(obj, target) {// 清除先前的定时器,只保留执行当前一个定时器clearInterval(obj.timer);obj.timer = setInterval(function() {// 步长值写到定时器的里面var step = (target - obj.offsetLeft) / 10;if (obj.offsetLeft == target) {// 停止动画 其实质是停止定时器clearInterval(obj.timer);}// 将每次加1这个步长值改为一个慢慢变小的值  步长公式:(目标值 - 当前位置) / 10obj.style.left = obj.offsetLeft + step + 'px';}, 15);}var span = document.querySelector('span');var btn = document.querySelector('button');btn.addEventListener('click', function() {// 调用函数animate(span, 500);})// 匀速动画 就是 盒子是当前的位置 +  固定的值 10 // 缓动动画就是  盒子当前的位置 + 变化的值(目标值 - 现在的位置) / 10)</script>

4.5 动画函数多个目标值之间移动

可以让动画函数从 800 移动到 500。
当点击按钮时,判断步长是正值还是负值

  1. 如果是正值,则步长 往大了取整;
  2. 如果是负值,则步长 向小了取整。

实例代码:

// 缓动动画函数封装
<button class="btn500">按钮1</button><button class="btn800">按钮2</button><span>文化长廊</span><script>// obj:目标对象;target:目标位置// 1. 让盒子每次移动的距离逐渐变小。// 2. 每次移动的距离(步长):(目标值 - 现在的位置) / 10 // 3. 停止条件: 当前盒子位置 = 目标位置时function animate(obj, target) {// 清除先前的定时器,只保留执行当前一个定时器clearInterval(obj.timer);obj.timer = setInterval(function() {// 步长值写到定时器的里面// 把步长值改为整数 避免出现小数// var step = Math.ceil((target - obj.offsetLeft) / 10);var step = (target - obj.offsetLeft) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step);if (obj.offsetLeft == target) {// 停止动画 其实质是停止定时器clearInterval(obj.timer);}// 将每次加1这个步长值改为一个慢慢变小的值  步长公式:(目标值 - 当前位置) / 10obj.style.left = obj.offsetLeft + step + 'px';}, 15);}var span = document.querySelector('span');var btn500 = document.querySelector('.btn500');var btn800 = document.querySelector('.btn800');btn500.addEventListener('click', function() {// 调用函数animate(span, 500);})btn800.addEventListener('click', function() {// 调用函数animate(span, 800);})// 匀速动画 就是 盒子是当前的位置 +  固定的值 10 // 缓动动画就是  盒子当前的位置 + 变化的值(目标值 - 现在的位置) / 10)</script>

4.6 动画函数添加回调函数

回调函数原理:
函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。
写回调函数的位置:定时器结束的位置。

4.7 动画函数封装到单独的JS文件

经常使用的动画函数,可单独封装到一个JS文件里,使用的时候引用此JS文件即可。

  1. 单独新建一个JS文件;
  2. HTML文件引入 JS 文件。

5. 常见网页特效案例

5.1 案例:网页轮播图(JavaScript原生写法)

5.1.1 功能需求:
1.鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮。
2.点击右侧按钮一次,图片往左播放一张,以此类推, 左侧按钮同理。
3.图片播放的同时,下面小圆圈模块跟随一起变化。
4.点击小圆圈,可以播放相应图片。
5.鼠标不经过轮播图, 轮播图也会自动播放图片。
6.鼠标经过,轮播图模块, 自动播放停止。

5.1.2 思路
① 单独新建js文件夹和js文件,并引入HTML页面中;
② 添加 load 事件;
③ 鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮;
④ 显示隐藏 display 按钮。

5.1.3 动态生成小圆圈
核心思路:
① 小圆圈的个数要跟图片张数一致;
② 首先得到ul里面图片的张数(图片放入li里面,所以就是li的个数);
③ 利用循环动态生成小圆圈(这个小圆圈要放入ol里面);
④ 创建节点 var li = createElement('li')
⑤ 插入节点 ol. appendChild(li)
⑥ 第一个小圆圈需要添加 current 类。

5.1.4 设定当前小圆圈(排他思想)
① 点击当前小圆圈,就添加current
② 其余的小圆圈就移除current

注: 在生成小圆圈的同时,就可直接绑定点击事件。

5.1.5 点击小圆圈滚动图片
① 需要用到animate动画函数,将js文件引入(注,因为index.js 依赖 animate.js 所以animate.js 要写到 index.js 上面);
② 使用动画函数的前提:该元素必须有定位;
③ 注意是ul 移动 而不是小li
④ 滚动图片的核心算法: 点击某个小圆圈 ,图片滚动。 ul移动距离=小圆圈的索引号×图片的宽;
⑤ 需要获取小圆圈的索引号,在生成小圆圈时,给它设置一个自定义属性,点击时获取此自定义属性即可。

5.1.6 点击右侧按钮,图片滚动
① 声明变量num, 每点击1次,num自增1, ul 滚动距离 = 变量 × 图片宽度

图片无缝滚动原理:
把ul 第一个li 复制一份,放到ul 的最后面;
当图片滚动到克隆的最后一张图片时, 让ul 快速的、不做动画的跳到最左侧: left 为0,同时num 赋值为0,从重新开始滚动图片

② 克隆第一张图片;克隆ul 第一个licloneNode()

复制里面的子节点。cloneNode()括号内加true 是深克隆, false 浅克隆。

③ 添加到 ul 最后面 appendChild

5.1.7 点击右侧按钮, 小圆圈跟随变化
① 再声明一个变量circle,每次点击自增1,因左右侧按钮都需要此变量,因此声明为全局变量。
② 但是图片张数比小圆圈多一个(首尾图片相同),需增加一个判断条件
③如有5张图片,则小圆点只能有4个,即判断写为 if(circle == 4) 就 从新复原为 0。

5.1.8 自动播放功能
① 添加定时器;

自动播放轮播图,实际就类似于点击了右侧按钮

② 此时可接手动调用右侧按钮点击事件(如 right_btn.click()
③ 鼠标经过轮播图focus 时,就停止定时器;
④ 鼠标离开focus则开启定时器。

5.2 节流阀

防止轮播图按钮连续点击造成播放过快。
节流阀目的:当上一个函数动画内容执行完毕,再执行下一个函数动画时,让事件无法连续触发。
实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。
开始设置一个变量 var flag = true;

If(flag) {flag = false; do something} // 关闭水龙头

利用回调函数 动画执行完毕, flag = true 打开水龙头。

5.2.1 案例:返回顶部
滚动窗口至文档中的特定位置。

window.scroll(x, y)

注意,里面的xy 不跟单位,直接写数字。

带有动画的返回顶部
① 此时可继续使用之前封装的动画函数;
② 只需把所有的left相关的值改为跟页面垂直滚动距离相关即可;
③ 页面滚动了多少,可通过 window.pageYOffset 获得;
④ 最后是页面滚动,使用 window.scroll(x,y)

javaScript PC端网页特效相关推荐

  1. JavaScript—— PC 端网页特效

    目录 一.PC 端网页特效 1. 元素偏移量 offest 系列 1.1 offset 概述 1.2 offset 与 style 区别 案例:获取鼠标在盒子内的坐标 案例:模拟框拖拽 html cs ...

  2. JavaScript——PC端网页特效

    目录 一.元素偏移量offset系列 1. offset概述 2. 常见属性 3. offset与style区别 案例--鼠标在盒子内坐标 案例--拖动模态框 案例--京东放大镜 二.元素可视区cli ...

  3. 移动端、PC端 网页特效

    移动端网页特效 标题触屏事件 移动端浏览器兼容性较好,不需要考虑以前 JS 的兼容性问题,可以放心的使用原生 JS 书写效果,但是移动端也有自己独特的地方.比如触屏事件 touch(也称触摸事件),A ...

  4. 05【JS 高级】-【PC端网页特效】元素偏移量 offset 系列, 元素可视区 client 系列, 元素滚动 scroll 系列, 动画函数封装, 常见网页特效案例

    04[JS 高级]-[PC端网页特效] 学习内容: 元素偏移量 offset 系列, 元素可视区 client 系列, 元素滚动 scroll 系列, 动画函数封装, 常见网页特效案例 1. 元素偏移 ...

  5. JS PC端网页特效 (一)

    2022年7月27日 周三学习记录博客  学习进度:PC端网页特效(一).学习时长:6h. 目录 PC端网页特效 1.元素偏移量 offset 系列 1.1 offset 概述 1.2 offset ...

  6. PC端网页特效二:mouseenter 和 mouseover 的区别、动画函数封装

      目录 5.mouseenter 和 mouseover 的区别 6.动画函数封装 动画实现原理 简单动画函数封装 动画函数给不同元素记录不同定时器 缓动效果原理 动画函数多个目标值之间移动 缓动函 ...

  7. 【第五部分 | JS WebAPI】6:PC端网页特效与本地存储

    目录 | 概述 | PC端网页特效之三大系列 1-1 elementObj . offsetXXX 属性 1-2 elementObj . style 和 offset 的区别 1-3 案例:获取鼠标 ...

  8. JavaScript(五)-- PC 端网页特效

    目录 1. 元素偏移量 offset 系列 1.1 offset 概述 1.2 offset 与 style 区别 案例:获取鼠标在盒子内的坐标 案例分析 案例:模态框拖拽 案例分析 案例:仿京东放大 ...

  9. JavaScript核心-5. PC端网页特效

    一.元素偏移量 offset 系列 1. offset offset 翻译过来就是偏移量, 我们使用 offset 系列相关属性可以动态的得到该元素的位置(偏移).大小等. 获得元素距离带有定位父元素 ...

最新文章

  1. git add . 之后 想执行回滚操作(git add 到本地仓库的代码回滚到没有add 之前的操作)
  2. Java 运算符 和 运算符
  3. Win32开发之Format MessageBox 详解
  4. numpy 数组 保留小数点后两位小数
  5. 一文解读“边缘计算” 和物联网的亲密关系!
  6. C++编程语言之标准化
  7. (非原)如何让.net开发的Winform程序快速释放内存
  8. Favicon尺寸?
  9. Swift - 高级运算符介绍
  10. android手机命令,使用adb命令操控Android手机(adb命令)
  11. PDF加密以及去除密码小妙招
  12. Vue - 图片放大镜(vue-piczoom)
  13. 海思Hi3798MV200机顶盒芯片规格书-基本信息
  14. 我在黑暗中看到你眼中的月光_你好黑暗,我的老朋友
  15. 经典时尚风格PS调色动作
  16. 万字长文带你探究 Docker 容器化技术背后的黑科技
  17. 秒杀系统架构设计与分析
  18. 28岁转行web前端,参加成都前端web培训可行吗?
  19. 为评职称!走捷径花钱发论文?骗你没商量!
  20. 【冒泡排序Java版】

热门文章

  1. linux创建新进程就分配空间,linux几种创建进程的方法
  2. Java 回调 (Callback) 接口学习使用
  3. springmvc整合mybatis之准备阶段与文件配置
  4. Spring详细导包截图以及IOC和DI思想
  5. sdut 数字三角形问题
  6. 数据结构实验之排序四:寻找大富翁
  7. std::mutex详解
  8. 使用IntelliJ IDEA导入 Flink 消费kafka报错 Error: A JNI error has occurred, please check your installation an
  9. 使用友盟+的APM服务实现对移动端APP的性能监控
  10. 前端如何快速上手 Web 3D 游戏的开发