PC端网页特效
1 元素偏移量 offset 系列
1.1 offset概述
使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等
- 获得元素距离带有定位父元素的位置, 如果父元素没有定位就返回距离body的距离
- 获得元素自身的大小(宽度高度)
1.2 offset使用
(1) 距离带有定位父元素的位置偏移
- offsetLeft
- offsetTop
(2) 得到元素的大小(包含padding和margin)
- offsetWidth
- offsetHeight
(3) 得到带有定位的父亲 (没有就是body)
offsetParent
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son')
// 距离带有定位父元素的位置偏移
console.log(father.offsetTop);
console.log(father.offsetLeft);
console.log(son.offsetLeft);
console.log(son.offsetTop);
// 得到元素的大小(包含padding和border)
console.log(son.offsetWidth);
console.log(son.offsetHeight);
// 得到带有定位的父亲,否则得到body
console.log(son.offsetParent);
</script>
</body>
2 元素可视区 client 系列
2.1 常见属性
- clientTop: 返回元素上边框的大小
- clientLeft:返回元素左边框的大小
- clientWidth:返回元素宽度(不包含边框,包含内边距)
- clientHeight:返回元素高度(不包含边框,包含内边距)
2.2 立即执行函数
不需要调用,立马就能执行的函数,下面是立即执行函数的声明方法
(function() {})() 或者 (function(){}())
<body>
<script>
// 立即执行函数最大的之作用就是独立创建一个作用域
// (function() {}) () (function() {} () )
(function(a) {
console.log(a);
})(1); // 后面这个小括号相当于调用函数,可以放参数,
(function(a){
console.log(a);
}(2));
</script>
</body>
3 元素滚动 scroll系列
3.1 scroll属性
- scrollTop:返回被卷去的上侧距离
- scrollLeft:返回被卷去的左侧距离
- scrollWidth:返回自身宽度(不带margin,带padding),与clientWidth不同的是, 当盒子不足放不下内容时,scrollWidth会返回内容宽度,而clientWidth只会返回盒子宽度
- scrollHeight:返回自身高度(不带margin,带padding),与clientHeight不同的是, 当盒子不足放不下内容时,scrollHeight会返回内容高度,而clientWidth只会返回盒子高度
3.2 案例:仿淘宝固定右侧侧边栏
- 页面被卷去的头部:可以通过window.pageYOffset 获得 如果是被卷去的左侧 window.pageXOffset
- 需要用到页面滚动事件 scroll 因为是页面滚动,所以事件源是 document
<body>
<div class="slider-bar">
<span class="goBack">返回顶部</span>
</div>
<div class="header w">头部区域</div>
<div class="banner w">banner区域</div>
<div class="main w">主体部分</div>
<script>
var sliderBar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');
var bannerTop = banner.offsetTop;
var sliderBarTop = sliderBar.offsetTop - bannerTop;
var main = document.querySelector('.main');
var goBack = document.querySelector('.goBack');
var mainTop = main.offsetTop;
document.addEventListener('scroll', function() {
// window.pageYOffset; 页面被卷去的高度,元素被卷去的头部是 element.scrollTop
if(pageYOffset >= bannerTop) {
sliderBar.style.position = 'fixed';
sliderBar.style.top = sliderBarTop + 'px';
}else {
sliderBar.style.position = 'absolute';
sliderBar.style.top = '300px';
}
if(pageYOffset >= mainTop) {
goBack.style.display = 'block';
}else {
goBack.style.display = 'none';
}
})
</script>
</body>
<style>
.slider-bar {
position: absolute;
/* left:50% 加上 margin-left: 600px 就是紧贴盒子右边 */
left: 50%;
top: 300px;
margin-left: 600px;
width: 45px;
height: 130px;
background-color: pink;
}
.w {
width: 1200px;
margin: 10px auto;
}
.header {
height: 150px;
background-color: purple;
}
.banner {
height: 250px;
background-color: skyblue;
}
.main {
height: 1000px;
background-color: yellowgreen;
}
span {
display: none;
position: absolute;
bottom: 0;
}
</style>
3.3 mouseenter 和mouseover的区别
- mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。 mouseenter 只会经过自身盒子触发
- 之所以这样,就是因为mouseenter不会冒泡
4 动画函数封装
4.1 原理
核心原理:通过定时器 setInterval() 不断移动盒子位置
实现步骤:
- 获得盒子当前位置
- 让盒子在当前位置加上1个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意此元素需要添加定位,才能使用element.style.left
<body>
<div></div>
<script>
var div = document.querySelector('div');
var moveTimer = setInterval(function() {
if(div.offsetLeft >= 600) {
clearInterval(moveTimer);
}
div.style.left = div.offsetLeft + 1 + 'px';
}, 30);
</script>
</body>
4.2 动画函数封装
<body>
<button>点我才走</button>
<div>
</div>
<script>
// 简单函数封装
// 如果多个元素都使用这个动画函数,每次都要var 声明定时器。我们可以给不同的元素使用不同的定时器
function animate(obj, target) {
// 保证只有一个定时器,如果不加 后面button多次点击会加速
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if(obj.offsetLeft >= target) {
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click', function() {
animate(div, 600);
})
</script>
</body>
4.3 缓动效果
4.3.1 原理
- 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来。
- 核心算法: (目标值 - 现在的位置 ) / 10 做为每次移动的距离 步长
- 停止的条件是: 让当前盒子位置等于目标位置就停止定时器
- 注意步长值需要取整
4.3.2 实现
<body>
<button>点我才走</button>
<div>
</div>
<script>
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var step = Math.ceil((target - obj.offsetLeft) / 10);
if(obj.offsetLeft === target) {
clearInterval(obj.timer);
}
obj.style.left = step + obj.offsetLeft + 'px';
}, 15);
}
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click', function() {
animate(div, 600);
})
</script>
</body>
4.3.2 缓动动画添加回调函数
<body>
<button>点我才走</button>
<div>
</div>
<script>
function animate(obj, target, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var step = Math.ceil((target - obj.offsetLeft) / 10);
if(obj.offsetLeft === target) {
clearInterval(obj.timer);
if(callback) {
callback();
}
}
obj.style.left = step + obj.offsetLeft + 'px';
}, 15);
}
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click', function() {
animate(div, 600, function() {
div.style.backgroundColor = 'red';
});
})
</script>
</body>