JavaScript学习7:PC端网页特效(offset、client、scroll、动画、轮播图、返回顶部、筋斗云)
文章目录
一、元素偏移量offset系列
element.offsetParent:返回带有定位的父亲,否则返回body
element.parentNode:返回最近一级的父亲
案例:拖动模态框
案例:仿京东放大镜
二、元素可视区client系列
立即执行函数 :不需要调用,立马执行,最大的作用就是独立创建了一个作用域,避免了命名冲突问题
(function(){})() :第二个括号可以看作调用函数
<script>
(function (a, b) {
console.log(a + b); //3
})(1, 2);
</script>
另一种写法:(function(){}())
其他要点:
1.pageshow和load区别
三、元素滚动scroll系列
scroll事件:滚动条发生变化事件
注意:mouseenter和mouseover的区别(面试题)
四、动画函数封装
动画原理:
- 获得盒子当前位置
- 让盒子在当前位置加上1个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意此元素需要添加定位,才能使用element.style.left
<script>
//动画原理
var div = document.querySelector('div');
var timer = setInterval(function () {
if (div.offsetLeft >= 400) {
//停止动画
clearInterval(timer);
} else {
div.style.left = div.offsetLeft + 1 + 'px';
}
}, 30);
</script>
简单动画函数封装:匀速
//简单动画函数封装 obj 目标对象 target 目标位置
function animate(obj, target) {
//防止开启了多个定时器
clearInterval(obj.timer);
//不使用var timer 会另外开辟空间 同时不能区分是谁的定时器
obj.timer = setInterval(function () {
if (obj.offsetLeft >= target) {
//停止动画
clearInterval(obj.timer);
} else {
obj.style.left = obj.offsetLeft + 1 + 'px';
}
}, 30);
}
var div = document.querySelector('div');
animate(div, 200);
缓动动画(更好看):减速效果
公式:(目标值 - 现在的位置) / 10
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();
}
// 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
五、常见网页特效案例
网页轮播图(shopping项目)
html:
<!-- 轮播图模块 -->
<div class="focus">
<!-- 中间滚动模块 -->
<ul>
<li>
<img src="upload/focus1.png" alt="">
</li>
<li>
<img src="upload/focus2.jpg" alt="">
</li>
<li>
<img src="upload/focus3.jpg" alt="">
</li>
<li>
<img src="upload/focus4.jpg" alt="">
</li>
<li>
<img src="upload/focus5.jpg" alt="">
</li>
</ul>
<!-- 左侧按钮 -->
<a href="javascript:;" class="prev"><</a>
<!-- 右侧按钮 -->
<a href="javascript:;" class="next">></a>
<!-- 底部小圆点 -->
<ol class="circle">
</ol>
</div>
css:
.focus {
position: relative;
float: left;
width: 721px;
height: 455px;
overflow: hidden;
}
/* 把装轮播图的盒子改大一些 必须有定位 才可以使用动画 */
.focus ul {
position: absolute;
top: 0;
left: 0;
width: 600%;
}
.focus ul li {
float: left;
}
.focus ul li img {
width: 721px;
height: 455px;
}
.prev,
.next {
display: none;
position: absolute;
top: 50%;
width: 30px;
height: 30px;
background: rgba(0, 0, 0, .3);
line-height: 30px;
text-align: center;
color: #fff;
}
.prev {
left: 0;
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
}
.next {
right: 0;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
}
.circle {
position: absolute;
left: 50%;
margin-left: -35px;
bottom: 15px;
height: 13px;
border-radius: 7px;
}
.circle li {
float: left;
width: 8px;
height: 8px;
background-color: #fff;
border-radius: 50%;
margin: 3px;
}
.circle .selected {
background-color: #ff5000;
}
js:
window.addEventListener('load', function () {
// 获取元素
var prev = document.querySelector('.prev');
var next = document.querySelector('.next');
var focus = document.querySelector('.focus');
//图片宽度
var focusWidth = focus.offsetWidth;
//1. 鼠标经过(离开)轮播图 显示(隐藏)左右按钮
focus.addEventListener('mouseenter', function () {
prev.style.display = 'block';
next.style.display = 'block';
//停止自动播放
clearInterval(timer);
timer = null;
})
focus.addEventListener('mouseleave', function () {
prev.style.display = 'none';
next.style.display = 'none';
//开启自动播放
timer = setInterval(function () {
//手动调用点击事件
next.click();
}, 2000);
})
//2. 动态生成小圆圈 与图片张数对应
var ul = focus.querySelector('ul');
var ol = focus.querySelector('.circle');
for (var i = 0; i < ul.children.length; i++) {
//创建一个li 并自定义索引属性
var li = document.createElement('li');
li.setAttribute('index', i);
//把li加入ol
ol.appendChild(li);
//3. 小圆圈的排他思想 改变颜色 改变图片
li.addEventListener('click', function () {
circleChange();
//改变图片 移动ul 移动距离:索引号*图片宽度 (负值)
var index = this.getAttribute('index'); //index控制图片播放
//同步num和circleNum
num = index; //num控制图片播放
circleNum = index; //circleNum控制小圆圈
animate(ul, -index * focusWidth);
})
}
//ol里的第一个li设置选中
ol.children[0].className = 'selected';
//4. 克隆第一张图片 不会影响小圆圈的个数
var first = ul.children[0].cloneNode(true);//深拷贝 true
ul.appendChild(first);
//5. 点击右侧按钮 图片滚动一张 小圆圈下一个
var num = 0;
var circleNum = 0;
var flag = true; //节流阀 防止图片滚动过快
next.addEventListener('click', function () {
if (flag) {
//无缝滚动 当是最后一张(最后一张与第一张相同)时,快速跳回第一张并重置num
if (num == ul.children.length - 1) {
ul.style.left = '0';
num = 0;
}
num++;
animate(ul, -num * focusWidth, function () {
flag = true;
});
//小圆圈显示下一个
circleNum++;
if (circleNum == ol.children.length) {
circleNum = 0;
}
circleChange();
}
});
//6. 左侧按钮
prev.addEventListener('click', function () {
if (flag) {
//无缝滚动 当是最后一张(最后一张与第一张相同)时,快速跳回第一张并重置num
if (num == 0) {
ul.style.left = -(ul.children.length - 1) * focusWidth + 'px';
num = ul.children.length - 1;
}
num--;
animate(ul, -num * focusWidth, function () {
flag = true;
});
//小圆圈显示下一个
circleNum--;
if (circleNum < 0) {
circleNum = ol.children.length - 1;
}
circleChange();
}
});
//7. 自动播放 (相当于点击右侧按钮)
var timer = setInterval(function () {
//手动调用点击事件
next.click();
}, 2000);
//排他处理
function circleChange() {
//干掉所有人
for (var j = 0; j < ol.children.length; j++) {
ol.children[j].className = '';
}
//留下我自己
ol.children[circleNum].className = 'selected';
}
})
animate.js见上节
返回顶部
页面滚动:window.scroll(x, y) 注意x和y不带px单位 这个滚动是没有动画的,因此可以手动添加动画。
筋斗云案例