目录
一、常见网页特效
1. 案例:网页轮播图
轮播图也称为焦点图,是网页中比较常见的网页特效。
功能需求:
- 鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮。
- 点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理。
- 图片播放的同时,下面小圆圈模块跟随一起变化。
- 点击小圆圈,可以播放相应图片。
- 鼠标不经过轮播图,轮播图也会自动播放图片。
- 鼠标经过,轮播图模块,自动播放停止。
1.1 案例分析
1.1.1 左右按钮的显示与隐藏
// 等页面所有元素加载完后再执行js
window.addEventListener('load', function () {
//this.alert('1'); // 测试
// 1. 获取元素
var arrow_l = this.document.querySelector('.arrow-l');
var arrow_r = this.document.querySelector('.arrow-r');
var focus = document.querySelector('.focus');
// 2. 鼠标经过focus 就显示隐藏的左右按钮
focus.addEventListener('mouseenter', function () {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
})
// 鼠标离开focus 就隐藏左右按钮
focus.addEventListener('mouseleave', function () {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
})
})
1.1.2 动态生成小圆圈
// 3. 动态生成小圆圈,有几张图片我们就生成几个小圆圈
var ul = focus.querySelector('ul');
var ol = focus.querySelector('.circle');
// console.log(ul.children.length); test
for (var i = 0; i < ul.children.length; i++) {
// 创建一个小li
var li = this.document.createElement('li');
// 把小li插入到ol里面
ol.appendChild(li);
}
// 把ol的第一个小li设置类名为 current
ol.children[0].className = 'current';
1.1.3 小圆圈的排他思想
排他思想的口诀: 干掉所有人,留下我自己
// 4. 小圆圈的排他思想 我们可以直接生成小圆圈的同时直接绑定点击事件
li.addEventListener('click', function () {
// 干掉所有人 把所有的小li 清除 current 类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = ' ';
}
// 留下我自己 当前的小li 设置current 类名
this.className = 'current';
})
把这段代码写到上一段代码的for循环里面
1.1.4 点击小圆圈滚动图片
html
css
js
for (var i = 0; i < ul.children.length; i++) {
// 创建一个小li
var li = this.document.createElement('li');
//记录当前小圆圈的索引号 通过自定义属性来做
li.setAttribute('index', i);
// 把小li插入到ol里面
ol.appendChild(li);
// 4. 小圆圈的排他思想 我们可以直接生成小圆圈的同时直接绑定点击事件
li.addEventListener('click', function () {
// 干掉所有人 把所有的小li 清除 current 类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = ' ';
}
// 留下我自己 当前的小li 设置current 类名
this.className = 'current';
// 5. 点击小圆圈,移动图片 当然移动的是 ul
// ul 的移动距离 小圆圈的索引号 乘以 图片的宽度 注意是往左走,所以是负值
// 当我们点击了某个小li 就拿到当前小li 的索引号
var index = this.getAttribute('index');
//console.log(index); test
var focusWidth = focus.offsetWidth;
//console.log(focusWidth); test
animate(ul, -index * focusWidth);
})
}
1.1.5 点击右侧按钮一次,就让图片滚动一张
将href的值 “#” 改写成 “javascript:;” ,使其被点击后不会跳到页面最顶端
将之前在for循环内部定义的focusWidth提到外面去定义,这样在外面也可以使用了。
将第一张的图片复制一份放到最后面
// 6. 点击右侧按钮一次,就让图片滚动一张
var num = 0;
arrow_r.addEventListener('click', function () {
// alert('1'); test
// 如果走到了最后复制的一张图片,此时,我们的ul 要快速复原 left 改为 0
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth);
})
1.1.6 克隆第一张图片
虽然右侧按钮的功能实现了,但我们还有代码改进的空间。
问题1: 我们的小li是直接在结构里面复制了一份,这样动态生成的小圆点也会随之增加。
问题2: 我们不知道里面到底有几张图片,在结构复制一份就写死了,能不能再自动化一些。
把之前在HTML文件里复制的第一张图片删掉。
// 6. 克隆第一张图片(li)放到ul 最后面
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
把该段代码写到上一段代码的前面。
因为在动态生成小圆圈之后再克隆了一份图片,所以小圆圈不会多一个。
1.1.7 点击右侧按钮,小圆圈跟随变化
// 7. 点击右侧按钮一次,就让图片滚动一张
var num = 0;
// circle 控制小圆圈的播放
var circle = 0;
arrow_r.addEventListener('click', function () {
// alert('1'); test
// 如果走到了最后复制的一张图片,此时,我们的ul 要快速复原 left 改为 0
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth);
// 8. 点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
circle++;
// 如果circle == 4 说明走到最后我们克隆的这张图片了 我们就复原为0
if (circle == ol.children.length) {
circle = 0;
}
// 先清除其余小圆圈的current类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 留下当前的小圆圈的current类名
ol.children[circle].className = 'current';
})
小bug
1.当我们点击第三个小圆圈会显示第3张图片,然后点击右侧按钮,图片却显示第2张。这是因为我们播放下一张是由num控制的,而num这一个变量和之前做的点击小圆圈事件没有任何关系,所以它们就出现差异。
// 4. 小圆圈的排他思想 我们可以直接生成小圆圈的同时直接绑定点击事件
li.addEventListener('click', function () {
// 干掉所有人 把所有的小li 清除 current 类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = ' ';
}
// 留下我自己 当前的小li 设置current 类名
this.className = 'current';
// 5. 点击小圆圈,移动图片 当然移动的是 ul
// ul 的移动距离 小圆圈的索引号 乘以 图片的宽度 注意是往左走,所以是负值
// 当我们点击了某个小li 就拿到当前小li 的索引号
var index = this.getAttribute('index');
//console.log(index); test
//当我们点击了某个小li 就要把这个小li 的索引号给 num
num = index;
//当我们点击了某个小li 就要把这个小li 的索引号给 circle circle是控制小圆圈自动播放
circle = index;
animate(ul, -index * focusWidth);
})
1.1.8 左侧按钮功能实现
// 7. 点击右侧按钮一次,就让图片滚动一张
var num = 0;
// circle 控制小圆圈的播放
var circle = 0;
arrow_r.addEventListener('click', function () {
// alert('1'); test
// 如果走到了最后复制的一张图片,此时,我们的ul 要快速复原 left 改为 0
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth);
// 8. 点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
circle++;
// 如果circle == 4 说明走到最后我们克隆的这张图片了 我们就复原为0
// if (circle == ol.children.length) {
// circle = 0;
// }
// 代码优化 三元表达式
circle = circle == ol.children.length ? 0 : circle;
// 调用函数
circleChange();
})
// 9. 左侧按钮做法
arrow_l.addEventListener('click', function () {
// alert('1'); test
// 如果走到了最后复制的一张图片,此时,我们的ul 要快速复原 left 改为 0
if (num == 0) {
num = ul.children.length - 1;
// ul向左走为负值
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWidth);
// 8. 点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
circle--;
// // 如果circle < 0 说明第一张图片 则小圆圈要改为第4个小圆圈
// if (circle < 0) {
// circle = ol.children.length - 1;
// }
// 代码优化 三元表达式
circle = circle < 0 ? ol.children.length - 1 : circle;
// 调用函数
circleChange();
})
// 优化 左右按钮的小圆圈排他思想代码一样 就封装为一个函数,调用函数 减少代码重复量
function circleChange() {
// 先清除其余小圆圈的current类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 留下当前的小圆圈的current类名
ol.children[circle].className = 'current';
}
1.1.9 自动播放功能
// 10. 自动播放轮播图
var timer = setInterval(function () {
// 手动调用点击事件
arrow_r.click();
}, 2000);
鼠标经过 focus 就停止定时器
鼠标离开 focus 就开启定时器
1.2 节流阀
// flag 节流阀
var flag = true;
arrow_r.addEventListener('click', function () {
if (flag) {
flag = false; // 关闭节流阀
// alert('1'); test
// 如果走到了最后复制的一张图片,此时,我们的ul 要快速复原 left 改为 0
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth, function () {
flag = true; // 打开节流阀
});
// 8. 点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
circle++;
// 如果circle == 4 说明走到最后我们克隆的这张图片了 我们就复原为0
// if (circle == ol.children.length) {
// circle = 0;
// }
// 代码优化 三元表达式
circle = circle == ol.children.length ? 0 : circle;
// 调用函数
circleChange();
}
})
1.3 代码展示
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="index.css">
<!-- 这个animate.js 必须写到 index.js的上面引入 -->
<script src="js/animate.js"></script>
<script src="js/index.js"></script>
</head>
<body>
<div class="focus">
<!-- 左侧按钮 -->
<a href="javascript:;" class="arrow-l"><</a>
<!-- 右侧按钮 -->
<a href="javascript:;" class="arrow-r">></a>
<!-- 核心的滚动区域 -->
<ul>
<li>
<a href="#"><img src="../images/focus.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="../images/focus1.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="../images/focus2.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="../images/focus3.jpg" alt=""></a>
</li>
</ul>
<!-- 小圆圈 -->
<ol class="circle">
</ol>
</div>
</body>
</html>
css
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
a {
text-decoration: none;
}
.focus {
position: relative;
width: 721px;
height: 455px;
background-color: pink;
margin: 100px auto;
overflow: hidden;
}
.focus ul {
position: absolute;
top: 0;
left: 0;
/* 使轮播图的使用图片都放到一行上去就需要扩大父盒子的宽度 */
width: 600%;
}
.focus ul li {
float: left;
}
.arrow-l, .arrow-r {
display: none;
position: absolute;
top: 50%;
margin-top: -20px;
width: 24px;
height: 40px;
background: rgba(0, 0, 0, .3);
text-align: center;
line-height: 40px;
color: #fff;
font-size: 18px;
z-index: 2;
}
.arrow-r {
right: 0;
}
.circle {
position: absolute;
bottom: 10px;
left: 50px;
}
.circle li {
float: left;
width: 8px;
height: 8px;
border: 2px solid rgba(255, 255, 255, 0.5);
margin: 0 3px;
border-radius: 50%;
/*鼠标经过显示小手*/
cursor: pointer;
}
.current {
background: #fff;
}
js
// 等页面所有元素加载完后再执行js
window.addEventListener('load', function () {
//this.alert('1'); // 测试
// 1. 获取元素
var arrow_l = this.document.querySelector('.arrow-l');
var arrow_r = this.document.querySelector('.arrow-r');
var focus = document.querySelector('.focus');
var focusWidth = focus.offsetWidth;
//console.log(focusWidth); test
// 2. 鼠标经过focus 就显示隐藏的左右按钮
focus.addEventListener('mouseenter', function () {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
clearInterval(timer);
timer = null; // 清除定时器变量
})
// 鼠标离开focus 就隐藏左右按钮
focus.addEventListener('mouseleave', function () {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
timer = setInterval(function () {
// 手动调用点击事件
arrow_r.click();
}, 2000);
})
// 3. 动态生成小圆圈,有几张图片我们就生成几个小圆圈
var ul = focus.querySelector('ul');
var ol = focus.querySelector('.circle');
// console.log(ul.children.length); test
for (var i = 0; i < ul.children.length; i++) {
// 创建一个小li
var li = this.document.createElement('li');
//记录当前小圆圈的索引号 通过自定义属性来做
li.setAttribute('index', i);
// 把小li插入到ol里面
ol.appendChild(li);
// 4. 小圆圈的排他思想 我们可以直接生成小圆圈的同时直接绑定点击事件
li.addEventListener('click', function () {
// 干掉所有人 把所有的小li 清除 current 类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = ' ';
}
// 留下我自己 当前的小li 设置current 类名
this.className = 'current';
// 5. 点击小圆圈,移动图片 当然移动的是 ul
// ul 的移动距离 小圆圈的索引号 乘以 图片的宽度 注意是往左走,所以是负值
// 当我们点击了某个小li 就拿到当前小li 的索引号
var index = this.getAttribute('index');
//console.log(index); test
//当我们点击了某个小li 就要把这个小li 的索引号给 num
num = index;
//当我们点击了某个小li 就要把这个小li 的索引号给 circle circle是控制小圆圈自动播放
circle = index;
animate(ul, -index * focusWidth);
})
}
// 把ol的第一个小li设置类名为 current
ol.children[0].className = 'current';
// 6. 克隆第一张图片(li)放到ul 最后面
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
// 7. 点击右侧按钮一次,就让图片滚动一张
var num = 0;
// circle 控制小圆圈的播放
var circle = 0;
// flag 节流阀
var flag = true;
arrow_r.addEventListener('click', function () {
if (flag) {
flag = false; // 关闭节流阀
// alert('1'); test
// 如果走到了最后复制的一张图片,此时,我们的ul 要快速复原 left 改为 0
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth, function () {
flag = true; // 打开节流阀
});
// 8. 点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
circle++;
// 如果circle == 4 说明走到最后我们克隆的这张图片了 我们就复原为0
// if (circle == ol.children.length) {
// circle = 0;
// }
// 代码优化 三元表达式
circle = circle == ol.children.length ? 0 : circle;
// 调用函数
circleChange();
}
})
// 9. 左侧按钮做法
arrow_l.addEventListener('click', function () {
if (flag) {
flag = false;
// alert('1'); test
// 如果走到了最后复制的一张图片,此时,我们的ul 要快速复原 left 改为 0
if (num == 0) {
num = ul.children.length - 1;
// ul向左走为负值
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWidth, function () {
flag = true;
});
// 8. 点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
circle--;
// // 如果circle < 0 说明第一张图片 则小圆圈要改为第4个小圆圈
// if (circle < 0) {
// circle = ol.children.length - 1;
// }
// 代码优化 三元表达式
circle = circle < 0 ? ol.children.length - 1 : circle;
// 调用函数
circleChange();
}
})
// 优化 左右按钮的小圆圈排他思想代码一样 就封装为一个函数,调用函数 减少代码重复量
function circleChange() {
// 先清除其余小圆圈的current类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 留下当前的小圆圈的current类名
ol.children[circle].className = 'current';
}
// 10. 自动播放轮播图
var timer = setInterval(function () {
// 手动调用点击事件
arrow_r.click();
}, 2000);
})
animate.js
function animate(obj, target, callback) {
// console.log(callback); callback = function() {} 调用的时候 callback()
// 先清除以前的定时器,只保留当前的一个定时器执行
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);
// 回调函数写到定时器结束里面
// if (callback) {
// // 调用函数
// callback();
// }
callback && callback(); // 短路运算符 如果callback 为true 就会执行后面的callback()
}
// 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
2. 案例:返回顶部
在之前 仿淘宝固定侧边栏的案例 中实现
js
// 3. 当我们点击了返回顶部模块,就让窗口滚动的页面的最上方
goBack.addEventListener('click', function () {
// alert(1);
// 里面的x和y 不跟单位的 直接写数字即可
// window.scroll(0, 0);
// 因为是窗口滚动 所以对象是window
animate(window, 0);
});
// 动画函数
function animate(obj, target, callback) {
// console.log(callback); callback = function() {} 调用的时候 callback()
// 先清除以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 步长值写到定时器的里面
// 把我们步长值改为整数 不要出现小数的问题
// var step = Math.ceil((target - obj.offsetLeft) / 10);
var step = (target - window.pageYOffset) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (window.pageYOffset == target) {
// 停止动画 本质是停止定时器
clearInterval(obj.timer);
// 回调函数写到定时器结束里面
// if (callback) {
// // 调用函数
// callback();
// }
callback && callback(); // 短路运算符 如果callback 为true 就会执行后面的callback()
}
// 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
// obj.style.left = window.pageYOffset + step + 'px';
window.scroll(0, window.pageYOffset + step);
}, 15);
}
3. 案例:筋斗云
鼠标经过某个小li,筋斗云跟这到当前小i位置
鼠标离开这个小li,筋斗云复原为原来的位置
鼠标点击了某个小li,筋斗云就会留在点击这个小li的位置
3.1 案例分析
3.2 代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style> * {
margin: 0; padding: 0; } ul {
list-style: none; } body {
background-color: black; } .c-nav {
width: 900px; height: 42px; background: #fff url(images/rss.png) no-repeat right center; margin: 100px auto; border-radius: 5px; position: relative; } .c-nav ul {
position: absolute; } .c-nav li {
float: left; width: 83px; text-align: center; line-height: 42px; } .c-nav li a {
color: #333; text-decoration: none; display: inline-block; height: 42px; } .c-nav li a:hover {
color: white; } .cloud {
position: absolute; left: 0; top: 0; width: 83px; height: 42px; background: url(images/cloud.gif) no-repeat; } </style>
<script src="animate.js"></script>
<script> window.addEventListener('load', function () {
// 1. 获取元素 var cloud = document.querySelector('.cloud'); var c_nav = document.querySelector('.c-nav'); var lis = c_nav.querySelectorAll('li'); // 这个current 做为筋斗云的起始位置 var current = 0; // 2. 给所有的小li绑定事件 for (var i = 0; i < lis.length; i++) {
// (1) 鼠标经过把当前小li 的位置做为目标值 lis[i].addEventListener('mouseenter', function () {
animate(cloud, this.offsetLeft); }); // (2) 鼠标离开就回到起始的位置 lis[i].addEventListener('mouseleave', function () {
animate(cloud, current); }); // (3) 当我们鼠标点击,就把当前位置做为目标值 lis[i].addEventListener('click', function () {
current = this.offsetLeft; }); } }) </script>
</head>
<body>
<div class="c-nav">
<span class="cloud"></span>
<ul>
<li class="current"><a href="">首页新闻</a></li>
<li><a href="#">师资力量</a></li>
<li><a href="#">活动策划</a></li>
<li><a href="#">企业文化</a></li>
<li><a href="#">招聘信息</a></li>
<li><a href="#">公司简介</a></li>
<li><a href="#">我是佩奇</a></li>
<li><a href="#">啥是佩奇</a></li>
</ul>
</div>
</body>
</html>
今天的文章JavaScript—— 常见网页特效分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/33865.html