目录
一、常见网页特效
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 克隆第一张图片
// 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);
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">
<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. 案例:筋斗云
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>

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201530.html原文链接:https://javaforall.net
