JavaScript核心知识第四章---PC端、移动端网页特效(含大量代码分析)

基础学习:

前端最基础的就是 HTML , CSS 和 JavaScript 。

网页设计:HTML和CSS基础知识的学习

HTML是网页内容的载体。内容就是网页制作者放在页面上想要让用户浏览的信息,可以包含文字、图片、视频等。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

CSS样式是表现。就像网页的外衣。比如,标题字体、颜色变化,或为标题加入背景图片、边框等。所有这些用来改变内容外观的东西称之为表现。

动态交互:JavaScript基础的学习

JavaScript是用来实现网页上的特效效果。如:鼠标滑过弹出下拉菜单。或鼠标滑过表格的背景颜色改变。还有焦点新闻(新闻图片)的轮换。可以这么理解,有动画的,有交互的一般都是用JavaScript来实现的。

| — | — |

| element.clientTop | 返回元素上边框的大小 |

| element.clientLeft | 返回元素左边框的大小 |

| element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |

| element.clientHeight | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |

2.1 案例:淘宝 flexible.js 源码分析

1️⃣ 立即执行函数 (function() {})()或者 (function(){}()),主要作用: 创建一个独立的作用域。 避免了命名冲突问题;

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

  • a标签的超链接

  • F5或者刷新按钮(强制刷新)

  • 前进后退按钮

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

3️⃣ 此时可以使用 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))


(3)元素滚动 scroll 系列

3.1 元素 scroll 系列属性

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

| scroll 系列属性 | 作用 |

| — | — |

| element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 |

| element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 |

| element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |

| element.scrollHeight | 返回自身实际的宽度,不含边框,返回数值不带单位 |

3.2 页面被卷去的头部

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

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

要求:

  1. 原先侧边栏是绝对定位;

  2. 当页面滚动到一定位置,侧边栏改为固定定位;

  3. 页面继续滚动,会让 返回顶部显示出来;

案例分析:

  1. 需要用到页面滚动事件 scroll 因为是页面滚动,所以事件源是 document;

  2. 滚动到某个位置,就是判断页面被卷去的上部值;

  3. 页面被卷去的头部:可以通过window.pageYOffset 获得 如果是被卷去的左侧 window.pageXOffset

  4. 注意,元素被卷去的头部是 element.scrollTop , 如果是页面被卷去的头部 则是 window.pageYOffset

  5. 其实这个值 可以通过盒子的 offsetTop 可以得到,如果大于等于这个值,就可以让盒子固定定位了;

完整代码演示如下:

Document

返回顶部

头部区域
主体部分
3.3 页面被卷去的头部兼容性解决方案

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

  1. 声明了 DTD,使用 document.documentElement.scrollTop;

  2. 未声明 DTD,使用 document.body.scrollTop;

  3. 新方法 window.pageYOffsetwindow.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

3.4 三大系列总结

| 三大系列大小对比 | 作用 |

| — | — |

| element.offsetWidth | 返回自身包括padding、边框、内容区的宽度、返回数值不带单位 |

| element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |

| element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |

😆主要用法😆:

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

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

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

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

3.5 mouseenter和mouseover的区别

1️⃣ 当鼠标移动到元素上时就会触发 mouseenter事件类似 mouseover;

2️⃣ 两者之间的差别是mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter 只会经过自身盒子触发;


(4)动画函数封装

4.1 动画实现原理

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

实现步骤:

  1. 获得盒子当前位置;

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

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

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

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

完整代码演示如下:

Document
4.2 动画函数简单封装

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

完整代码演示如下:

Document

欢迎来到我的博客哦

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

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

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

完整代码演示如下:

Document

点击我才能走呢

欢迎来到我的博客哦

4.4 缓动效果原理

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

😆思路😆:

  1. 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来;

  2. 核心算法: (目标值 - 现在的位置 ) / 10 做为每次移动的距离 步长;

  3. 停止的条件是: 让当前盒子位置等于目标位置就停止定时器;

  4. 注意步长值需要取整;

完整代码演示如下:

Document

点击我才能走呢

欢迎来到我的博客哦

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

可以让动画函数从 800 移动到 500;

当我们点击按钮时候,判断步长是正值还是负值

  1. 如果是正值,则步长 往大了取整;

  2. 如果是负值,则步长 向小了取整;

完整代码演示如下:

Document

点击我到500啦

点击我到800啦

欢迎来到我的博客哦

4.6 动画函数添加回调函数

1️⃣ 回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。

2️⃣ 回调函数写的位置:定时器结束的位置。

完整代码演示如下:

Document

点击我到500啦

点击我到800啦

欢迎来到我的博客哦


二、移动端网页特效


(1)触屏事件

1.1 触屏事件概述

1️⃣ 移动端浏览器兼容性较好,我们不需要考虑以前 JS 的兼容性问题,可以放心的使用原生 JS 书写效果,但是移动端也有自己独特的地方。比如触屏事件 touch(也称触摸事件),Android 和 IOS 都有。

2️⃣ touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。

| 触屏touch事件 | 说明 |

| — | — |

| touchstact | 手指触摸一个DOM元素时触发 |

| touchmove | 手指在一个DOM元素上滑动时触发 |

| touchend | 手指在一个DOM元素上移开时触发 |

完整代码演示如下:

Document
1.2 触摸事件对象(TouchEvent)

1️⃣ TouchEvent是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少等;

2️⃣ touchstarttouchmovetouchend 三个事件都会各自有事件对象;

触摸事件对象重点我们看三个常见对象列表:

| 触摸列表 | 说明 |

| — | — |

| touches | 正在触摸屏幕的所有手指的一个列表 |

| targetTouches | 正在触摸当前DOM元素上的手指的一个列表 |

| changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |

😆温馨提醒😆:因为平时我们都是给元素注册触摸事件,所以重点记住 targetTocuhes

1.3 移动端拖动元素

1️⃣ touchstarttouchmovetouchend 可以实现拖动元素;

2️⃣ 但是拖动元素需要当前手指的坐标值 我们可以使用 targetTouches[0] 里面的pageXpageY

3️⃣ 移动端拖动的原理:手指移动中,计算出手指移动的距离。然后用盒子原来的位置 + 手指移动的距离;

4️⃣ 手指移动的距离:手指滑动中的位置 减去 手指刚开始触摸的位置;

拖动元素三步曲:

  1. 触摸元素 touchstart:获取手指初始坐标,同时获得盒子原来的位置;

  2. 移动手指 touchmove:计算手指的滑动距离,并且移动盒子;

  3. 离开手指 touchend:;

😆温馨提醒😆:手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动 e.preventDefault();

完整代码演示如下:

Document

(2)补充知识

2.1 classList 属性

classList属性是HTML5新增的一个属性,返回元素的类名。但是ie10以上版本支持。

该属性用于在元素中添加,移除及切换 CSS 类。有以下方法:

  1. 添加类:element.classList.add('类名');

focus.classList.add(‘current’);

  1. 移除类:element.classList.remove('类名');

focus.classList.remove(‘current’);

  1. 切换类:element.classList.toggle('类名');

focus.classList.toggle(‘current’);

😆温馨提醒😆:以上方法里面,所有类名都不带点;

完整代码演示如下:

Document

开关灯

2.2 click 延时解决方案

移动端 click 事件会有 300ms 的延时,原因是移动端屏幕双击会缩放(double tap to zoom) 页面。

😆解决方案😆:

  1. 禁用缩放。 浏览器禁用默认的双击缩放行为并且去掉 300ms 的点击延迟;
  1. 利用touch事件自己封装这个事件解决 300ms 延迟。原理如下:

1️⃣ 当我们手指触摸屏幕,记录当前触摸时间;

2️⃣ 当我们手指离开屏幕, 用离开的时间减去触摸的时间;

3️⃣ 如果时间小于150ms,并且没有滑动过屏幕, 那么我们就定义为点击;

//封装tap,解决click 300ms 延时

function tap (obj, callback) {

var isMove = false;

var startTime = 0; // 记录触摸时候的时间变量

obj.addEventListener(‘touchstart’, function (e) {

startTime = Date.now(); // 记录触摸时间

});

obj.addEventListener(‘touchmove’, function (e) {

isMove = true; // 看看是否有滑动,有滑动算拖拽,不算点击

});

obj.addEventListener(‘touchend’, function (e) {

if (!isMove && (Date.now() - startTime) < 150) { // 如果手指触摸和离开时间小于150ms 算点击

callback && callback(); // 执行回调函数

}

isMove = false; // 取反 重置

startTime = 0;

});

}

//调用

tap(div, function(){ // 执行代码 });

  1. 使用插件。 fastclick 插件解决 300ms 延迟。

❗️ ❗️ GitHub官网地址:https://github.com/ftlabs/fastclick/blob/main/lib/fastclick.js


❤️ 谢谢支持

喜欢的话别忘了 关注、点赞哦~。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

前端校招面试题精编解析大全

yle>

.bg {

background-color: black;

}

开关灯

2.2 click 延时解决方案

移动端 click 事件会有 300ms 的延时,原因是移动端屏幕双击会缩放(double tap to zoom) 页面。

😆解决方案😆:

  1. 禁用缩放。 浏览器禁用默认的双击缩放行为并且去掉 300ms 的点击延迟;
  1. 利用touch事件自己封装这个事件解决 300ms 延迟。原理如下:

1️⃣ 当我们手指触摸屏幕,记录当前触摸时间;

2️⃣ 当我们手指离开屏幕, 用离开的时间减去触摸的时间;

3️⃣ 如果时间小于150ms,并且没有滑动过屏幕, 那么我们就定义为点击;

//封装tap,解决click 300ms 延时

function tap (obj, callback) {

var isMove = false;

var startTime = 0; // 记录触摸时候的时间变量

obj.addEventListener(‘touchstart’, function (e) {

startTime = Date.now(); // 记录触摸时间

});

obj.addEventListener(‘touchmove’, function (e) {

isMove = true; // 看看是否有滑动,有滑动算拖拽,不算点击

});

obj.addEventListener(‘touchend’, function (e) {

if (!isMove && (Date.now() - startTime) < 150) { // 如果手指触摸和离开时间小于150ms 算点击

callback && callback(); // 执行回调函数

}

isMove = false; // 取反 重置

startTime = 0;

});

}

//调用

tap(div, function(){ // 执行代码 });

  1. 使用插件。 fastclick 插件解决 300ms 延迟。

❗️ ❗️ GitHub官网地址:https://github.com/ftlabs/fastclick/blob/main/lib/fastclick.js


❤️ 谢谢支持

喜欢的话别忘了 关注、点赞哦~。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

[外链图片转存中…(img-gBlfwBgS-1715783281684)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值