六、移动端特效
6.1 触屏事件
移动端浏览器的兼容性较好,不需要考虑JS的兼容新问题。
6.1.1 常见的触屏事件
触屏事件 | 事件说明 |
touchstart |
手指触摸DOM 元素事件 |
touchmove |
手指在DOM元素身上移动 事件 |
touchend |
手指离开DOM 元素事件 |
// 手指触摸DOM元素事件 var div = document.querySelector('div'); div.addEventListener('touchstart', function() { console.log('我摸了你'); }); // 手指在DOM元素身上移动事件 div.addEventListener('touchmove', function() { console.log('我继续摸'); }); // 手指离开DOM元素事件 div.addEventListener('touchend', function() { console.log('轻轻的我走了'); });
6.1.2 触摸事件对象(TouchEvent)
触摸事件常用事件对象列表
触摸列表 | 说明 |
touches | 正在触摸屏幕的所有手指的一个列表 |
targeTouches | 正在触摸当前DOM元素上的手指的一个列表(常用) |
changedTouches | 手指状态发生了改变的列表,从无到有,从有到无的变化 |
6.1.3 移动端拖动元素
使用到以上的三种触摸事件
拖动元素需要获取到手指的坐标值: targetTouches[0] 的pageX和pageY
原理:手指移动中,计算出手指移动的距离,然后用盒子原来的位置 + 手指移动的距离
手指移动的距离:手指滑动中的位置 减去 手指刚开始触摸的位置坐标
主要就是三步骤:
触摸元素 touchstart: 获取手指初始坐标,同时获得盒子原来的位置
移动手指 touchmove:计算手指的滑动距离,并且移动盒子
离开手指 touchend:手指移动也会触发滚动屏幕,阻止默认的屏幕滚动 e.preventDefault()
<body> <div></div> <script> // 1.获取元素 var div = document.querySelector('div'); // 2.获取手指、盒子初始位置坐标 var fingerX = 0; var fingerY = 0; var boxX = 0; var boxY = 0; // 3.手指开始触摸事件 div.addEventListener('touchstart', function (e) { // 获取到初始值坐标 fingerX = e.targetTouches[0].pageX; fingerY = e.targetTouches[0].pageY; boxX = this.offsetLeft; boxY = this.offsetTop; }) // 4. 手指移动事件 div.addEventListener('touchmove', function (e) { // 手指移动的距离计算,移动后的坐标减去初始值的坐标 var moveX = e.targetTouches[0].pageX - fingerX; var moveY = e.targetTouches[0].pageY - fingerY; // 盒子的移动距离,盒子原来的坐标加上手指移动的距离 this.style.left = boxX + moveX + 'px'; this.style.top = boxY + moveY + 'px'; // 阻止屏幕的滚动行为 e.preventDefault(); }) </script> </body>
6.2 移动端特效
移动端轮播图
HTML
<!-- 焦点图模块 --> <div class="focus"> <ul class="total"> <li><img src="upload/focus3.jpg" alt=""></li> <li><img src="upload/focus1.jpg" alt=""></li> <li><img src="upload/focus2.jpg" alt=""></li> <li><img src="upload/focus3.jpg" alt=""></li> <li><img src="upload/focus1.jpg" alt=""></li> </ul> <!-- 小圆点 --> <ol> <li class="current"></li> <li></li> <li></li> </ol> </div>
CSS
.focus { position: relative; padding-top: 44px; overflow: hidden; } .focus img { width: 100%; } .focus ul { overflow: hidden; width: 500%; margin-left: -100%; } .focus ul li { float: left; width: 20%; } .focus ol { position: absolute; bottom: 5px; right: 5px; margin: 0; } .focus ol li { display: inline-block; width: 5px; height: 5px; background-color: #fff; list-style: none; border-radius: 2px; transition: all .3s; } .focus ol li.current { width: 15px; }
JS
window.addEventListener('load', function () { // 1. 获取元素 var focus = document.querySelector('.focus'); var total = document.querySelector('.total'); var ul = focus.children[0]; // 获得focus的宽度 var w = focus.offsetWidth; var ol = focus.children[1]; // 2. 利用定时器自动轮播图图片 var index = 0; var timer = setInterval(function () { index++; // 左移动 为负值 var translatex = -index * w; // 过度效果 ul.style.transition = 'all .3s'; ul.style.transform = 'translateX(' + translatex + 'px)'; }, 2000); // 等过渡完成之后,再去判断 监听过渡完成的事件 transitionend ul.addEventListener('transitionend', function () { // 无缝滚动 if (index >= total.children.length - 2) { index = 0; // 去掉过渡效果 这样让我们的ul 快速的跳到目标位置 ul.style.transition = 'none'; // 利用最新的索引号乘以宽度 去滚动图片 var translatex = -index * w; ul.style.transform = 'translateX(' + translatex + 'px)'; } else if (index < 0) { index = 2; ul.style.transition = 'none'; // 利用最新的索引号乘以宽度 去滚动图片 var translatex = -index * w; ul.style.transform = 'translateX(' + translatex + 'px)'; } // 3. 小圆点跟随变化 // 把ol里面li带有current类名的选出来去掉类名 remove ol.querySelector('.current').classList.remove('current'); // 让当前索引号的小li加上 current add ol.children[index].classList.add('current'); }); // 4. 手指滑动轮播图 var startX = 0; var moveX = 0; // 后面我们会使用这个移动距离所以要定义一个全局变量 var flag = false; // 触摸元素 touchstart: 获取手指初始坐标 ul.addEventListener('touchstart', function (e) { startX = e.targetTouches[0].pageX; // 手指触摸的时候就停止定时器 clearInterval(timer); }); // 移动手指 touchmove: 计算手指的滑动距离, 并且移动盒子 ul.addEventListener('touchmove', function (e) { // 计算手指移动距离 moveX = e.targetTouches[0].pageX - startX; // 移动盒子: 盒子原来的位置 + 手指移动的距离 var translatex = -index * w + moveX; // 手指拖动的时候,不需要动画效果所以要取消过渡效果 ul.style.transition = 'none'; ul.style.transform = 'translateX(' + translatex + 'px)'; flag = true; // 如果用户手指移动过再去判断否则不做判断效果 e.preventDefault(); // 阻止滚动屏幕的行为 }); // 手指离开 根据移动距离去判断是回弹还是播放上一张下一张 ul.addEventListener('touchend', function (e) { if (flag) { // (1) 如果移动距离大于50像素我们就播放上一张或者下一张 if (Math.abs(moveX) > 50) { // 如果是右滑就是 播放上一张 moveX 是正值 if (moveX > 0) { index--; } else { // 如果是左滑就是 播放下一张 moveX 是负值 index++; } var translatex = -index * w; ul.style.transition = 'all .3s'; ul.style.transform = 'translateX(' + translatex + 'px)'; } else { // (2) 如果移动距离小于50像素我们就回弹 var translatex = -index * w; ul.style.transition = 'all .1s'; ul.style.transform = 'translateX(' + translatex + 'px)'; } } // 手指离开的时候就重新开启定时器 clearInterval(timer); timer = setInterval(function () { index++; var translatex = -index * w; ul.style.transition = 'all .3s'; ul.style.transform = 'translateX(' + translatex + 'px)'; }, 2000); }); // 返回顶部模块制作 var goBack = document.querySelector('.goBack'); var localNav = document.querySelector('.local-nav'); window.addEventListener('scroll', function () { if (window.pageYOffset >= localNav.offsetTop) { goBack.style.display = 'block'; } else { goBack.style.display = 'none'; } }); goBack.addEventListener('click', function () { window.scroll(0, 0); }) })
classList
返回元素的类名
<body> <div class="one two"></div> <button> 开关灯</button> <script> // classList 返回元素的类名 var div = document.querySelector('div'); console.log(div.classList[1]);// 获取类名 // 1. 添加类名 是在后面追加类名不会覆盖以前的类名 注意前面不需要加. div.classList.add('three'); // 2. 删除类名 div.classList.remove('one'); // 3. 切换类 var btn = document.querySelector('button'); btn.addEventListener('click', function() { document.body.classList.toggle('bg'); }) </script> </body>
click 延时事件
移动端click事件会有300ms的延时,原因是移动端屏幕双击会缩放(double tap to zoom
)页面。
解决方案:
- 禁用缩放。浏览器禁用默认的双击缩放行为并且去掉300ms的点击延迟。
<meta name="viewport" content="user-scalable=no">
- 利用
touch
事件自己封装这个事件解决300ms延迟。
原理就是:
1.当我们手指触摸屏幕,记录当前触摸时间 2.当我们手指离开屏幕,用离开的时间减去触摸的时间 3.如果时间小于150ms ,并且没有滑动过屏幕,那么我们就定义为点击 封装tap,解决click 300ms延时
6.3 移动端开发插件开发移动端特效
6.3.1 使用插件。fastclick 插件解决300ms延迟。
<body> <div></div> <script> if ('addEventListener' in document) { document.addEventListener('DOMContentLoaded', function() { FastClick.attach(document.body); }, false); } var div = document.querySelector('div'); div.addEventListener('click', function() { console.log('这个div'); }) </script> </body>
点击 pink 正方形:
6.3.2 swiper 插件
6.3.3 superslide 插件
6.3.4 iscroll 插件
插件使用总结
- 确认插件的功能
- 官网查看插件说明
- 下载插件
- 查看demo实例文件,查看需要引入的相关文件,(JS、CSS),并且引入到
index.html
中 - 复制demo的中代码到对应的 js、html、css中
6.3.5 视频插件
6.4 移动端开发框架开发移动端特效
Vue
React
Angular
七、本地存储
本地存储特性
- 数据存储的浏览器中
- 设置、读取方便、页面刷新不丢失数据
- 容量较大、
sessionStorage
约5M,localStorage
约为20M - 只能存储字符串、可以将
JSON.stringify()
编码后存储
7.1 sessionStorage
介绍
- 生命周期为关闭浏览器窗口
- 在同一个窗口(页面)下数据可以共享
- 以键值对的形式存储
存储数据
sessionStorage.setItem(key,value)
<body> <input type="text"> <button class="set">存储数据</button> <script> var ipt = document.querySelector('input'); var set = document.querySelector('.set'); // 存储数据 set.addEventListener('click',function (){ var value = ipt.value; sessionStorage.setItem('username',value); }) </script> </body>
获取数据
sessionStorage.getItem(key) • 1
删除数据
sessionStorage.removeItem(key) • 1
删除所有数据
sessionStorage.clear() • 1
<body> <input type="text"> <button class="set">存储数据</button> <button class="get">获取数据</button> <button class="remove">删除数据</button> <button class="del">清空所有数据</button> <script> var ipt = document.querySelector('input'); var set = document.querySelector('.set'); // 存储数据 set.addEventListener('click', function () { var value = ipt.value; sessionStorage.setItem('username', value); sessionStorage.setItem('pwd', value); }) // 获取数据 get.addEventListener('click', function () { sessionStorage.getItem('username'); }) // 删除单个数据 remove.addEventListener('click', function () { sessionStorage.removeItem('username'); sessionStorage.removeItem('pwd'); }) // 清除所有的 del.addEventListener('click', function () { sessionStorage.clear(); }) </script> </body>
7.2 localStorage
- 生命周期永久生效,除非处于手动删除,否则关闭页面也会存在
- 可以多窗口(页面)共享,同一浏览器可以共享
- 以键值对形式存储使用
获取数据
localStorage.setItem(key,value); • 1
获取数据
localStorage.getItem(key) • 1
删除数据
localStorage.removeItem(key)
删除所有数据
localStorage.clear() • 1
<body> <input type="text"> <button class="set">存储数据</button> <button class="get">获取数据</button> <button class="remove">删除数据</button> <button class="del">清空所有数据</button> <script> var ipt = document.querySelector('input'); var set = document.querySelector('.set'); var get = document.querySelector('.get'); var remove = document.querySelector('.remove'); var del = document.querySelector('.del'); set.addEventListener('click', function() { var val = ipt.value; localStorage.setItem('username', val); }) get.addEventListener('click', function() { console.log(localStorage.getItem('username')); }) remove.addEventListener('click', function() { localStorage.removeItem('username'); }) del.addEventListener('click', function() { localStorage.clear(); }) </script> </body>
案例
记住账号密码案例,方便下次进来可以直接使用,不用再次输入
<body> <input type="text" id="username"> <input type="checkbox" name="" id="remember"> 记住用户名 <br> <input type="text" id="password"> <input type="checkbox" name="" id="rememberpwd"> 记住密码 <script> // 获取元素事件 var username = document.querySelector('#username'); var reusername = document.querySelector('#remember'); var inputPwd = document.querySelector('#password'); var repwd = document.querySelector('#rememberpwd'); // 在本次存储中获取用户名,密码 if (localStorage.getItem('username') || localStorage.getItem('passwd')) { username.value = localStorage.getItem('username'); reusername.checked = true; inputPwd.value = localStorage.getItem('passwd'); repwd.checked = true; } // 记住用户名的复选框 reusername.addEventListener('change', function () { if (this.checked) { localStorage.setItem('username', username.value) } else { localStorage.removeItem('username'); } }) // 记住密码的复选框 repwd.addEventListener('change', function () { if (this.checked) { localStorage.setItem('password', inputPwd.value); } else { localStorage.removeItem('password'); } }) </script> </body>
当复选框都够选上时:数据存储到本地
取消勾选,数据将不会保存的本地
到此学习JS 的BOM、DOM学习完毕,其中还有许多的还没有掌握,还需要多敲代码,加油码农!!❤️❤️🔥
get.addEventListener(‘click’, function() {
console.log(localStorage.getItem(‘username’));
}) remove.addEventListener('click', function() { localStorage.removeItem('username'); }) del.addEventListener('click', function() { localStorage.clear(); }) </script>
```
[外链图片转存中…(img-JvTqZAPD-1671521678477)]
案例
记住账号密码案例,方便下次进来可以直接使用,不用再次输入
<body> <input type="text" id="username"> <input type="checkbox" name="" id="remember"> 记住用户名 <br> <input type="text" id="password"> <input type="checkbox" name="" id="rememberpwd"> 记住密码 <script> // 获取元素事件 var username = document.querySelector('#username'); var reusername = document.querySelector('#remember'); var inputPwd = document.querySelector('#password'); var repwd = document.querySelector('#rememberpwd'); // 在本次存储中获取用户名,密码 if (localStorage.getItem('username') || localStorage.getItem('passwd')) { username.value = localStorage.getItem('username'); reusername.checked = true; inputPwd.value = localStorage.getItem('passwd'); repwd.checked = true; } // 记住用户名的复选框 reusername.addEventListener('change', function () { if (this.checked) { localStorage.setItem('username', username.value) } else { localStorage.removeItem('username'); } }) // 记住密码的复选框 repwd.addEventListener('change', function () { if (this.checked) { localStorage.setItem('password', inputPwd.value); } else { localStorage.removeItem('password'); } }) </script> </body>
当复选框都够选上时:数据存储到本地
[外链图片转存中…(img-f79o4Ny9-1671521678479)]
取消勾选,数据将不会保存的本地
[外链图片转存中…(img-EIcGIAcQ-1671521678481)]
到此学习JS 的BOM、DOM学习完毕,其中还有许多的还没有掌握,还需要多敲代码,加油码农!!❤️❤️🔥