PC端网页特效
1. 元素偏移量offset系列
(1). offset概述
// 1.1 offset概述
var father = document.querySelector('.father');
var son = document.querySelector('.son');
// 1. 可以得到元素的偏移,位置,返回的不带单位的数值
console.log(father.offsetTop);
console.log(father.offsetLeft);
// 它以带有定位的父亲为准,如果没有父亲或者父亲没有定位,则以body为准
console.log(son.offsetLeft);
// 1. 可以得到元素的大小,宽度和高度,是包含了padding + border + width
var w = document.querySelector('.w');
console.log(w.offsetWidth);
console.log(w.offsetHeight);
// 1. 返回带有定位的父亲,否则返回的是body
console.log(son.offsetParent); // 返回带有定位的父亲,否则返回的是body
console.log(son.parentNode); // 返回父亲,是最近一级的父亲,亲爸爸,不管父亲有没有定位
(2). offset 和 style 区别
// offset 和 style 区别
var box = document.querySelector('.box');
console.log(box.offsetWidth);
console.log(box.style.width);
// box.offsetWidth = '300px';
box.style.width = '300px';
实例:获得鼠标在盒子内的坐标
// 实例;获得鼠标在盒子内的坐标
var son = document.querySelector('.son');
son.addEventListener('click', function(e) {
console.log(e.pageY);
console.log(this.offsetTop);
console.log(e.pageX);
console.log(this.offsetLeft);
son.innerHTML = 'X: ' + (e.pageX - this.offsetLeft) +'y: '+ (e.pageY - this.offsetTop);
})
实例:模态框拖拽
var w = document.querySelector('.w');
var body =document.body;
var top1;
var left;
function fn(a) {
left = a.pageX;
top1 = a.pageY;
var x = left - 50;
var y = top1 - 50;
w.style.top = y + 'px';
w.style.left = x + 'px';
console.log(left);
}
w.addEventListener('mousedown',function() {
w.addEventListener('mousemove', fn);
w.addEventListener('mouseup', function() {
w.removeEventListener('mousemove',fn);
})
});
实例:仿京东放大镜
<div class="boxz">
<div class="box3">
<div class="box1"></div>
</div>
</div>
<div class="box2"><img src="1.jpg" alt="" class="imgs" ></div>
<script>
// 仿京东放大镜
var box3 = document.querySelector('.box3');
var box2 = document.querySelector('.box2');
var box1 = document.querySelector('.box1');
var img1 = document.querySelector('.imgs');
box3.addEventListener('mousemove', function(e) {
var le = (e.pageX - 50) ;
var to = (e.pageY - 50) ;
if ((e.pageX>=this.offsetLeft+50)&&(e.pageX<=this.offsetLeft+150)) {
box1.style.left = le + 'px';
var x1 = (le - this.offsetLeft)*img1.offsetWidth/box2.offsetWidth;
console.log(img1.offsetWidth/box2.offsetWidth);
img1.style.left= -x1 + 'px';
}
if ((e.pageY>=this.offsetTop+50)&&(e.pageY<=this.offsetTop+150)) {
box1.style.top = to + 'px';
var y1 = (to - this.offsetTop)*img1.offsetHeight/box2.offsetHeight;
console.log(img1.offsetHeight/box2.offsetHeight);
img1.style.top = -y1 + 'px';
}
})
</script>
2. 元素可视区client系列
案例:淘宝flexible.js源码分析
3. 元素滚动scroll系列
(1). 元素scroll系列属性
<div class="qqq">
我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容
我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容
我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容
我是内容我是内容我是内容我是内容我是内容我是内容
</div>
<script>
// 3.1 元素scroll系列属性
// scroll 系列
console.log(666666);
var div = document.querySelector('.qqq');
console.log(div.scrollHeight);
console.log(div.clientHeight);
// scroll 滚动事件当我们滚动条发生变化会触发事件
div.addEventListener('scroll', function() {
console.log(div.scrollTop);
})
</script>
实例:拖动滚动条停留侧边
<!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>
body{
margin: 0px;
padding: 0px;
border: 0px;
}
.nei {
width: 600px;
height: 2000px;
position:absolute;
background-color: aqua;
}
.daohang {
width: 100px;
height: 200px;
top: 300px;
background-color: blue;
left: 500px;
position: absolute;
}
</style>
</head>
<body>
<div class="nei">
<div class="daohang"></div>
</div>
<script>
var zong = document.querySelector('.zong');
var div = document.querySelector('.nei');
var daohang = document.querySelector('.daohang');
document.addEventListener('scroll', function(){
var tp = window.pageYOffset;
console.log(tp);
if (tp>300) {
daohang.style.position = 'fixed';
// daohang.style.left = 506 + 'px';
daohang.style.top = 0 +'px';
console.log(tp);
}else {
daohang.style.position = 'absolute';
// daohang.style.left = 500 + 'px';
daohang.style.top = 300 +'px';
}
})
</script>
</body>
</html>
(2). 页面被卷去的头部兼容性解决方案
// 需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:
// 1. 声明了DTD,使用document.documentElement.scrollTop
// 2. 未声明DTD, 使用document.body.scrollTop
// 3. 新方法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
(3). 三大系列总结
(4). mouseenter 和 mosueover的区别
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son');
father.addEventListener('mouseenter', function() {
console.log(11);
})
</script>
4. 动画函数封装
(1). 动画实现原理
(2). 动画函数简单封装
<script>
// 动画原理
// 1. 获得盒子位置
// 2. 让盒子在当前位置加上一个移动距离
// 3. 利用定时器不断重复这个动作
// 4. 加一个结束定时器的条件
// 5. 注意此元素需要添加定位,才能使用element.style.left
var div = document.querySelector('div');
function animate(obj, target) {
// 当我们不断点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
// 解决方案就是让我们元素只有一个定时器执行
clearInterval(obj.timer); // 让我们元素只有一个定时器执行
obj.timer = setInterval(function(){
if (obj.offsetLeft >= target) {
// 停止动画,本质是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
},30);
}
var div = document.querySelector('div');
animate(div, 300);
</script>
(3). 缓冲效果原理
<script>
// 动画原理
// 1. 获得盒子位置
// 2. 让盒子在当前位置加上一个移动距离
// 3. 利用定时器不断重复这个动作
// 4. 加一个结束定时器的条件
// 5. 注意此元素需要添加定位,才能使用element.style.left
var div = document.querySelector('div');
function animate(obj, target) {
// 当我们不断点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
// 解决方案就是让我们元素只有一个定时器执行
clearInterval(obj.timer); // 让我们元素只有一个定时器执行
obj.timer = setInterval(function(){
var step = (target - obj.offsetLeft)/10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft >= target) {
// 停止动画,本质是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
},30);
}
var div = document.querySelector('div');
animate(div, 300);
</script>
(4). 动画函数多个目标值之间移动
(5). 动画函数添加回调函数
// 回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,
// 再执行传进去的这个函数,这个过程就叫回调。
// 回调函数写的位置:定时器结束的位置
<script>
// 动画原理
// 1. 获得盒子位置
// 2. 让盒子在当前位置加上一个移动距离
// 3. 利用定时器不断重复这个动作
// 4. 加一个结束定时器的条件
// 5. 注意此元素需要添加定位,才能使用element.style.left
var div = document.querySelector('div');
function animate(obj, target, callback) {
// 当我们不断点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
// 解决方案就是让我们元素只有一个定时器执行
clearInterval(obj.timer); // 让我们元素只有一个定时器执行
obj.timer = setInterval(function(){
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();
}
}
obj.style.left = obj.offsetLeft + step + 'px';
},30);
}
var div = document.querySelector('div');
function callback() {
div.style.backgroundColor = 'red';
}
animate(div, 300, callback);
</script>
(6). 动画函数封装到单独JS文件里面
因为以后经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可
案例:网页轮播图
<!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>网页轮播图</title>
<style>
.small {
width: 300px;
height: 200px;
position: relative;
}
.big {
width: 1500px;
height: 200px;
position: absolute;
}
.dian {
top: 150px;
width: 300px;
height: 50px;
position: absolute;
}
.ul1 {
width: 1500px;
padding: 0;
margin: 0;
position:absolute;
}
.li {
display: none;
width: 300px;
height: 200px;
list-style: none;
}
.ul2 {
width: 300px;
height: 50px;
padding: 0;
margin: 0;
position:absolute;
}
.li1 {
width: 60px;
height: 50px;
list-style: none;
background-color:blue ;
float: left;
}
img {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="small">
<div class="big">
<ul class="ul1">
<li class="li"><img src="1.jpg" alt=""></li>
<li class="li"><img src="/tu/1.jpg" alt=""></li>
<li class="li"><img src="/tu/2.jpg" alt=""></li>
<li class="li"><img src="/tu/3.jpg" alt=""></li>
<li class="li"><img src="/tu/4.jpg" alt=""></li>
</ul>
</div>
<div class="dian">
<ul class="ul2">
<li class="li1">1</li>
<li class="li1">2</li>
<li class="li1">3</li>
<li class="li1">4</li>
<li class="li1">5</li>
</ul>
</div>
</div>
<script>
var lis = document.querySelectorAll('.li');
var ls = document.querySelectorAll('.li1');
var div = document.querySelector('.big');
var sum;
var gun = function(p){
// lis[0].style.display = 'block';
sum= p;
lis[p].style.display = 'block';
ls[p].style.backgroundColor = 'red';
div.timer = setInterval(function(){
sum+=1;
console.log(sum);
for (var i = 0; i < 5 ; i++) {
if(i===sum%5) {
lis[i].style.display = 'block';
ls[i].style.backgroundColor = 'red';
}else {
lis[i].style.display = 'none';
ls[i].style.backgroundColor = 'blue';
}
}
},1000);
}
gun(0);
for (var j=0 ;j<5; j++) {
ls[j].index = j;
ls[j].addEventListener('mouseover', function() {
console.log(div.timer);
var t = sum % 5;
console.log('shuzi'+t);
lis[t].style.display = 'none';
ls[t].style.backgroundColor = 'blue';
clearInterval(div.timer);
gun(this.index);
clearInterval(div.timer);
})
ls[j].addEventListener('mouseout', function() {
gun(this.index);
})
}
</script>
</body>
</html>