目录
一.PC端网页特效
1.元素偏移量offset系列
(1)概述
偏移量, offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小(宽度高度)
- 注意: 返回的数值都不带单位
(2)常见属性:
注意:
- 无right和bottom
- parentNode 属性也可返回父元素, 但返回为最近一级(亲)父元素 无论有无定位
(3)offset与style比较
2.元素可视区client系列
(1)概述
客户端,client 翻译过来就是客户端,使用 client 系列的相关属性来获取元素可视区的相关信息。动态得到该元素的边框大小、元素大小
(2)常见属性
(3)clientWidth与offsetWidth
- clientWidth / clientHeight: 不包含自身边框,但有专门的属性获取
- offsetWidth / offsetHeight: 包含自身边框
3.元素滚动scroll系列
(1)概述
滚动的,与滚动条有关,使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等
(2)常见属性
(3)页面被卷去的头部
- 如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条. 当滚动条向下滚动时,页面上面被隐藏掉的高度, 就称为页面被卷去的头部。
- overflow: auto; 自动出现滚动条
- 滚动条在滚动时会触发 onscroll 事件。div.addEventListener('scroll',function(){ });
兼容性问题:
被卷去的头部通常有如下几种写法:
- 声明了 DTD,使用 document.documentElement.scrollTop
- 未声明 DTD,使用 document.body.scrollTop
- 新方法 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
(4)三大系列总结
主要用法:
- offset系列 常用于获得元素位置 offsetLeft offsetTop
- client常用于获取元素大小 clientWidth clientHeight
- scroll常用于获取滚动距离scrollTop,scrollLeft ,页面滚动的距离通过window.pageXOffset获得
4.立即执行函数
- 不需要调用,立马能够自己执行的函数
- 写法: (function() {})() 或者 (function(){}()) 前边的括号可写形参,最后边的小括号可看做调用函数,其中也可写实参
- 主要作用: 创建一个独立的作用域,里边的变量都是局部变量,避免了命名冲突问题
5.flexible.js源码分析
(function flexible(window, document) {
// 像素比
var docEl = document.documentElement; // 获取的html 的根元素
var dpr = window.devicePixelRatio || 1 ; // dpr 物理像素比 若没有此属性,则当1来看 PC和手机端大小不一样
// adjust body font size 设置body字体大小
function setBodyFontSize() {
if (document.body) {// 如果页面中有body元素 就设置body的字体大小
document.body.style.fontSize = (12 * dpr) + 'px'
} else { // 如果页面中没有body这个元素,则等页面主要的DOM元素加载完毕再去设置body的字体大小
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10 设置html元素的文字大小 flexible是将屏幕划分为若干等分,一个等分为1rem
function setRemUnit() {
var rem = docEl.clientWidth / 10; //html宽度/10
docEl.style.fontSize = rem + 'px';
}
setRemUnit()
//pageshow 重新加载页面触发的事件
/* 刷新页面都会触发 load 事件的方式: a标签的超链接, F5或者刷新按钮(强制刷新),前进后退按钮 */
/* 火狐“往返缓存”,这个缓存中保存着页面数据,DOM和JavaScript的状态;实际上是将整个页面都保存在了内存里,所以此时后退按钮不能刷新页面,可使用 pageshow事件来触发这个事件在页面显示时触发,无论页面是否来自缓存,在重新加载页面中,pageshow会在load事件触发后触发;根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件,注意这个事件给window添加 */
// reset rem unit on page resize 当我们页面尺寸大小发生变化时,要重新设置rem 的大小
window.addEventListener('resize', setRemUnit);
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))
6.mouseenter 和mouseover的区别
当鼠标移动到元素上时就会触发 mouseenter 事件, 类似 mouseover
两者之间的差别:
- mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发, 触发2次
- mouseenter 只会经过自身盒子触发,因为mouseenter不会冒泡, 触发1次
- 跟mouseenter搭配,鼠标离开 mouseleave 同样不会冒泡
7.动画函数封装
(1)动画原理
核心原理: 通过定时器 setInterval() 不断移动盒子位置
实现步骤:
- 获得盒子当前位置
- 让盒子在当前位置加上1个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意此元素需要添加定位,才能使用element.style.left
(2)动画函数简单封装
注意函数需要传递2个参数,动画对象和移动到的距离
(3) 动画函数给不同元素记录不同定时器(函数优化)
原因1:
- 如果多个元素都使用这个动画函数,每次都要var 声明定时器(浪费内存空间,且定时器名字同容易引起歧义).
- 解决方案: 可以给不同的元素使用不同的定时器(不同类元素自己专门用自己的定时器)
- 核心原理:利用 JS 是一门动态语言,可以很方便的给当前对象添加属性
原因2:
- 添加按钮点击触发事件, 如果不断点击,速度会越来越快
- 解决方案: 元素只有一个定时器 先清除以前的定时器,只保留当前一个定时器执行
(4)缓动效果原理
让元素运动速度有所变化,最常见的是让速度慢慢停下来
思路:
- 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
- 核心算法: (目标值 - 现在的位置 ) / 10(可改) 作为每次移动的距离(步长)
- 停止的条件是: 让当前盒子位置等于目标位置就停止定时器 注意步长值需要取整
(5)动画函数多个目标值之间移动
点击按钮时候,判断步长是正还是负值: 若是正值,则步长往大了取整,若是负值,则步长向小了取整
(6) 动画函数添加回调函数
回调函数原理:函数可以作为一个参数, 将这个函数作为实参传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。
回调函数写的位置:定时器结束的位置
(7)动画函数封装到单独JS文件里面
经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可
单独新建一个JS文件, HTML文件引入 JS 文件
// 匀速动画: 盒子当前位置 + 固定位置 当前位置offsetLeft
// 缓动动画: 盒子当前位置 + 步长step 停止条件: 当前盒子位置等于目标位置就停止定时器
// 函数优化: 给不同元素指定不同定时器 目标对象obj,目标位置target
function animate(obj,target,callback){ //callback接收实参function(){}函数 ,函数调用写在清除定时器里
//当不断点击按钮,此元素速度会越来越快, 解决方案: 元素只有一个定时器 先清除以前的定时器,只保留当前一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function(){
// 步长值写在定时器的里面 将步长值改为整数,避免小数到不了目标位置
var step = (target - obj.offsetLeft) / 10;
//缓动动画:可实现多个目标值之间移动(步长改为整数的原因) 正数则向上取整Math.ceil(), 负数则向下取整Math.floor()
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == target){
clearInterval(obj.timer);// 停止动画 清除定时器
//回调函数的调用写在清除定时器里,如果有回调函数则执行,没有则不执行
if(callback){
callback();
}
}
obj.style.left = obj.offsetLeft + step + 'px';
},15);
}
// 获取对象 函数调用 (可更改定时器中间隔时间)
var div = document.querySelector('.box1');
var box = document.querySelector('.box2');
var btn500 = document.querySelector('.btn500');
var btn800 = document.querySelector('.btn800');
animate(div,1000);
btn500.addEventListener('click',function(){
// 调用函数 可将函数function(){}作为实参传给callback形参
animate(box,500,function(){
alert('移动结束!');
});
})
btn800.addEventListener('click',function(){
animate(box,800);
})
8.常见网页特效案例
(1)轮播图/焦点图
实现功能:
1. 鼠标经过轮播图模块,显示左右按钮,离开隐藏
2. 每点击左右按钮,切换一张图片
3. 图片播放同时,小圆点一起变化
4. 点击小圆点,播放相应图片 (使用动画函数,元素必须有定位,ul移动而不是li ul移动距离=小圆点的索引号 * 图片的宽度 (向左走,为负 得到索引号:设置自定义属性,点击时获取))
5. 鼠标不经过轮播图,则自动播放
6. 鼠标经过时,轮播图停止自动播放
实现步骤:
1.获取元素
2.鼠标经过轮播图模块,显示左右按钮(btn.style.display),轮播图自动播放停止(清除定时器,清除定时器变量);鼠标离开按钮隐藏,自动播放开启(开启定时器,手动调用点击事件btn_right.click();)
3.动态生成小圆点 获取ul中li的个数ul.children.length,利用for循环放入ol中 (创建节点creatElement('li'); 插入节点ol.appendChild(li); 同时记录当前小圆点的索引号,自定义属性得到li.setAttribute('index',i); 把ol中第一个li的类名设置为current)
4.小圆点绑定点击事件 排他思想(写在生成小圆点的循环中) 清除所有li的类名current,设置当前li的类名current
5.点击小圆点,移动图片(写在点击事件中) ul移动距离=小圆点的索引号 * 图片的宽度 得到索引号getAttribute('index'),动画调用 当点击某个li, 将其索引号给num和circle (解决bug,避免点击圆点再点击右按钮,播放的图片不对)
6.克隆第一张图片(li),放到ul最后面 克隆写在生成小圆点的后边
7.每点击右按钮,切换一张图片 节流阀{}
8.小圆点跟随右侧按钮一起变化
9.左侧安钮
10. 自动播放轮播图 定时器 类似点击右侧按钮,使用手动调用右侧按钮点击事件
其他:
1.动态生成小圆点: 小圆点个数与图片个数同, 先得到ul中li个数,利用for循环放入ol中 创建节点creatElement('li'),插入节点ol.appendChild(li)
2.小圆点排他思想 生成时绑定点击事件
3.图片无缝滚动: 克隆第一张图放在ul最后,当要滚动到时,让ul快速不做动画跳到最左侧left:0; 同时num=0,可以新开始滚动 cloneNode() true深克隆,复制子节点,false浅克隆
4.小圆点跟随右侧按钮一起变化: 声明一个全局变量circle,每次点击自增1,左侧按钮也需要
5.节流阀: 回调函数,添加变量flag,锁住和解锁函数 true 防止轮播图连续点击造成播放过快
(2)返回顶部
- window.scroll(x,y); 滚动到某位置, 不写单位 顶部(0,0)
- 实现缓慢滚动到某位置: 可添加动画函数,将left相关值改为页面垂直滚动距离window.pageYoffset相关即可
(3)筋斗云
给所有li绑定事件,鼠标经过时当前li位置为目标值,鼠标离开时回到起始位置,鼠标点击时把当前位置作为目标值,把当前位置存储起来,作为筋斗云的起始位置
二.移动端网页特效
1.触屏事件
(1)概述
- 移动端浏览器兼容性较好,不需要考虑以前 JS 的兼容性问题,可以放心的使用原生 JS 书写效果,但是移动端也有自己独特的地方. 比如触屏事件 touch()也称触摸事件),Android 和 IOS 都有
- touch 对象代表一个触摸点,触摸点可能是一根手指,也可能是一根触摸笔. 触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作
(2)常见触屏事件
(3)触摸事件对象TouchEvent
- 描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件,这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等
- touchstart, touchmove, touchend三个事件都会各自有事件对象,常见对象列表:
(4) 移动端拖动元素
touchstart、touchmove、touchend 添加事件可实现拖动元素
移动端拖动的原理:
- 移动后盒子位置(this.style.left/top) = 盒子原来位置(x/y) + 手指移动距离(moveX/Y) + 'px';
- 手指移动距离(moveX/Y) = 手指移动后坐标(e.targetTouches[0].pageX/Y) - 手指初始坐标(startX/Y 自定义)
拖动元素三步曲:
- 触摸元素 touchstart: 获取手指初始坐标,同时获得盒子原来的位置
- 移动手指 touchmove: 计算手指的滑动距离,并且移动盒子
- 离开手指 touchend: 注意: 手指移动也会触发滚动屏幕,故需阻止默认的屏幕滚动 e.preventDefault(); 加在最后即可
2.移动端常见特效
(1)轮播图
1.轮播图自动播放 定时器 ul.style.transition = 'all 0.5s';过渡效果
2.过渡完成后再判断 监听过渡完成的事件transitionend
3.小圆点跟随图片变化 去掉原来current,添加类名
4.手指滑动轮播图 只有左右 触摸,滑动 离开
(2)classList属性
HTML5新增的一个属性,返回元素的类名, 但是ie10以上版本支持,移动端不影响, 该属性用于在元素中添加,移除及切换 CSS 类。
- 添加类 element.classList.add(’类名’);
- 移除类 element.classList.remove(’类名’);
- 切换类 element.classList.toggle(’类名’); 注意以上方法里面,所有类名都不带点
(3) click 延时解决方案
移动端 click 事件会有 300ms 的延时,原因是移动端屏幕双击会缩放(double tap to zoom) 页面
解决方案:
- 禁用缩放. 浏览器禁用默认的双击缩放行为并且去掉 300ms 的点击延迟 <meta name="viewport" content="user-scalable=no">
- 利用touch事件自己封装这个事件解决 300ms 延迟(原理: 手指触摸屏幕,记录当前触摸时间, 手指离开屏幕,用离开的时间减去触摸的时间, 如果时间小于150ms,并且没有滑动过屏幕, 那么我们就定义为点击), 若有多个事件需要,则需要多次调用,麻烦
- 使用插件, fastclick 插件解决 300ms 延迟
//封装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(){ // 执行代码 });
3.移动端常用开发插件
(1)概念
JS 插件是 js 文件,它遵循一定规范编写,方便程序展示效果,拥有特定功能且方便调用。如轮播图和瀑布流插件。
特点:它一般是为了解决某个问题而专门存在,其功能单一,并且比较小 e.g: animate.js 也算一个最简单的插件
(2)常用插件
①fastclick插件
- 解决300ms延迟,使用延时 GitHub官网地址: https://github.com/ftlabs/fastclick
- 引入 js 插件文件 <script src='./fastclick.js'></script>, 按照规定语法使用 (相应网址上有代码,复制到写js的模块中)
②Swiper插件
- 轮播图 中文官网地址: https://www.swiper.com.cn/
- 下载并引入插件相关文件(css,js文件), 按照规定语法使用
<!-- 引入swipercss文件 --> <link rel="stylesheet" href="css/swiper.min.css"> <!-- 引入swiperjs文件 --> <script src="./js/swiper-bundle.min.js"></script> <!-- 引入自定义js文件 因为自己写的依赖于引入的,故引入时写在引入的swiper.js文件下--> <script src="./js/index.js"></script> <link rel="stylesheet" href="./css/index.css">
③superslide插件
焦点图,图片/无缝滚动,tab标签切换 http://www.superslide2.com/
④iscroll插件
https://github.com/cubiq/iscroll
⑤zy.media.js移动端视频插件
H5提供了 video 标签,但浏览器的支持情况不同. 不同的视频格式文件, 可以通过source 解决. 但外观样式,还有暂停,播放,全屏等功能只能自己写代码解决, 可使用插件方式来制作(解决视频在不同浏览器上播放的效果不一的问题)
(3)插件使用
- 确认插件实现的功能
- 去官网查看使用说明
- 下载插件
- 打开demo实例文件,查看需要引入的相关文件,并且引入
- 复制demo实例文件中的结构html,样式css以及js代码
4.移动端常用开发框架
(1)概念
- 框架,就是一套架构,它会基于自身的特点向用户提供一套较为完整的解决方案。
- 框架的控制权在框架本身,使用者要按照框架所规定的某种规范进行开发。
框架与插件比较:
- 框架: 大而全, 提供一套较为完整的解决方案,
- 插件: 小而专一(其功能单一),某个功能的解决方案
(2)常用框架
- 前端常用的框架有Bootstrap、Vue、Angular、React 等. 既能开发PC端, 也能开发移动端
- 前端常用的移动端插件有 swiper、superslide、iscroll等
(3)Bootstrap框架
Bootstrap 是一个简洁、直观、强悍的前端开发框架,它让 web 开发更迅速、简单。 它能开发PC端,也能开发移动端
Bootstrap JS插件使用步骤:
- 引入相关js 文件
- 复制HTML 结构
- 修改对应样式
- 修改相应JS 参数
三.本地存储
1.简介
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。
特性:
- 数据存储在用户浏览器中
- 设置、读取方便、甚至页面刷新不丢失数据
- 容量较大,sessionStorage约5M、localStorage约20M
- 只能存储字符串,可以将对象JSON.stringify() 编码后存储
2.window.sessionStorage
(1)特性
- 生命周期为关闭浏览器窗口
- 在同一个窗口(页面)下数据可以共享
- 以键值对的形式存储使用 e.g: ('uname', value)
(2)使用
- 存储数据 window.sessionStorage.setItem(key , value); window均可省 e.g: ('uname', value)
- 获取数据 sessionStorage.getItem(key);
- 删除数据 sessionStorage.removeItem(key);
- 清空数据 sessionStorage.clear(); 清除所有数据
3.window.localStorage
(1)特性
- 声明周期永久生效,除非手动删除 否则关闭页面也会存在
- 可以多窗口(页面)共享(同一浏览器可以共享) (其他页面也可以直接打印)
- 以键值对的形式存储使用
(2)使用
- 存储数据 window.localStorage.setItem(key , value); window均可省 e.g: ('uname', value)
- 获取数据 localStorage.getItem(key);
- 删除数据 localStorage.removeItem(key);
- 清空数据 localStorage.clear(); 清除所有数据