PC端网页特效
元素偏移量offset系列
概述
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小(宽度、高度)
- 返回的数值不带单位
常用属性
- element.offsetParent 返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body
注:
- offsetParent 返回带有定位的父级元素
- parentNode 返回最近一级的父级元素
- element.offsetTop 返回元素相对带有定位父元素上方的偏移
- element.offsetLeft 返回元素相对带有定位父元素左边框的偏移
- element.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
- element.offsetHeight 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
offset与style
offset | style | |
---|---|---|
作用 | 可以得到任意样式表中的样式值 | 行内样式表中的样式值 |
返回值 | 不带单位的数值 | 带有单位的字符串 |
width 返回值 | padding+border+width的数值 | 不包含padding和border的值 |
属性 | offsetWidth等属性是只读属性,只能获取不能赋值 | style.width是可读写属性,可获取也可赋值 |
适用 | 获取元素大小位置 | 更改元素值 |
元素可视区client系列
概述
使用client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态得到该元素的边框大小、元素大小等。
常用属性
- element.clientTop 返回元素上边框的大小
- element.clientLeft 返回元素左边框的大小
- element.clientWidth 返回自身包括padding、内容区宽度,不含边框,返回数值不带单位
- element.clientHeight 返回自身包括padding、内容区高度,不含边框,返回数值不带单位
元素滚动scroll系列
概述
使用scroll系列的相关属性可以动态地得到该元素的大小、滚动距离等
常用属性
- element.scrollTop 返回被卷去的上侧距离,返回数值不带单位
- element.scrollLeft 返回被卷去的左侧距离,返回数值不带单位
- element.scrollWidth 返回自身实际的宽度,不含边框,返回数值不带单位
- element.scrollHeight 返回自身实际的高度,不含边框,返回数值不带单位
页面卷去头部兼容性解决方案
function getScroll(){
return(
left:window.pageXOffset || document.documentElement.scrollLeft||document.body.scrollLeft||0,
top:window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0
);
}
三大系列
三大系列 | 作用 | 主要用法 |
---|---|---|
element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回数值不带单位 | 获取元素位置 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 | 获取元素大小 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 | 获取滚动距离 |
页面滚动距离通过 window.pageXOffset获得
flexible.js源码分析
立即执行函数
- 含义:不需要调用,能够立马执行函数
- 主要作用:创建一个独立的作用域,避免了命名冲突问题
- 语法规范:
- (function(形参){})(实参);
- (function(形参){}(实参));
pageshow
触发load事件的情况
- a标签的超链接
- F5或刷新按钮(强制刷新)
- 前进后退按钮
火狐浏览器有“往返缓存”,后退的时候不能刷新页面。针对这一问题,使用pageshow,在页面显示时触发,无论是否来自缓存,都会重新加载页面。
pageshow 只针对window元素
persisted属性,判断页面是否来自于缓存
mouseenter和mouseover
mouseenter
鼠标移动到元素上时就会触发,只会经过自身盒子触发。不会冒泡。搭配mouseleave,也不会冒泡
mouseover
鼠标移动到元素上时就会触发,经过子盒子还会触发。会冒泡,搭配mouseout
封装简单动画函数
function simpleflash(obj, target, step, time) {
var timer = setInterval(function() {
if (obj.offsetLeft > target) {
clearInterval(timer);
} else {
obj.style.left = obj.offsetLeft + step + 'px';
}
}, time);
}
simpleflash(flash, 400, 10, 50);
动画实现原理
核心原理: 通过定时器setInterval()不断移动盒子位置
实现步骤:
- 获得盒子当前位置
- 让盒子在当前位置加上移动距离
- 利用定时器不断重复操作
- 添加结束定时器的条件
- 元素需要添加定位 ,才能使用element.style.left
动画函数给不同元素记录不同定时器
核心原理: 利用JS是一门动态语言,可以方便地给当前对象添加属性
function simpleflash(obj, target, step, time) {
//若定时器是由其他事件进行触发,触发一次,就会开启一个定时器,不断触发,定时器会越来越多,元素移动速度会越来越快
//先清除以前的定时器,再保留当前定时器
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if (obj.offsetLeft > target) {
clearInterval(obj.timer);
} else {
obj.style.left = obj.offsetLeft + step + 'px';
}
}, time);
}
simpleflash(obj1, 400, 10, 50);
simpleflash(obj2, 400, 10, 50);
缓动效果
缓动效果原理: 让元素运动速度有所变化,常见的就是减速运动
思路:
- 让盒子每次移动距离慢慢变小
- 核心算法:(目标值-当前位置)/步长
动画函数多个目标值之间移动
- 移动步长为正值,上取整
- 移动步长为负值,下取整
function simpleflash(obj, target, step, time) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var adv = (target - obj.offsetLeft) / step; //减速
adv = adv > 0 ? Math.ceil(adv) : Math.floor(adv); //前进上取整,后退下取整
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
} else {
// obj.style.left = obj.offsetLeft + step + 'px';//匀速
obj.style.left = obj.offsetLeft + adv + 'px';
}
},
time);
}
var btnShort = document.querySelector('#btnShort');
var btnLong = document.querySelector('#btnLong');
btnShort.addEventListener('click', function() {
simpleflash(flash, 500, 10, 50);
})
btnLong.addEventListener('click', function() {
simpleflash(flash, 1000, 10, 50);
})
动画函数添加回调函数
回调函数原理: 函数作为一个参数传到另一个函数里,当该函数执行完后,再执行传进去的函数,整个过程叫做回调。
function simpleflash(obj, target, step, time, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var adv = (target - obj.offsetLeft) / step; //减速
adv = adv > 0 ? Math.ceil(adv) : Math.floor(adv); //前进上取整,后退下取整
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
if (callback) {
callback();
}
} else {
// obj.style.left = obj.offsetLeft + step + 'px';//匀速
obj.style.left = obj.offsetLeft + adv + 'px';
}
},
time);
}
常见的网页特效
网页轮播图
轮播图,也称为焦点图
功能需求:
- 鼠标经过轮播图模块,显示左右按钮,离开隐藏左右按钮
- 点击右侧按钮,图片往左播放一张,点击左侧按钮,图片往右播放一张
- 图片滚动同时,下侧索引模块跟随变化
- 点击下侧索引模块,播放相应图片
- 鼠标不经过轮播图,轮播图自动播放
节流阀
目的: 当上一个函数动画内容执行完毕,再执行下一个函数动画,让事件无法连续触发。防止轮播图按钮连续点击造成播放过快。(I see:有时候连续点击,就是想加快速度啊)
核心实现思路: 利用回调函数,添加变量控制,对动画函数进行封锁和解锁。
//轮播图
var focus = document.querySelector('.focus');
var left = document.querySelector('.arrow-l');
var right = document.querySelector('.arrow-r');
var target = focus.offsetWidth;
focus.addEventListener('mouseenter', function() {
left.style.display = 'block';
right.style.display = 'block';
clearInterval(timer);
timer = null;
});
focus.addEventListener('mouseleave', function() {
left.style.display = 'none';
right.style.display = 'none';
timer = setInterval(function() {
right.click();
}, 3000);
});
//动态生成小圆圈
var ul = focus.querySelector('ul');
var ol = focus.querySelector('.circle');
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
//记录小圆圈的索引号
li.setAttribute('index', i);
ol.appendChild(li);
li.addEventListener('click', function() {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
this.className = 'current';
//点击小圆圈,移动图片
var index = this.getAttribute('index');
num = index;
circle = index;
simpleflash(ul, -index * target, 10, 5)
})
}
ol.children[0].className = 'current';
//克隆第一张图片
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
//点击按钮,滚动
var num = 0;
var circle = 0;
//定义变量,控制动画函数
var flag = true;
right.addEventListener('click', function() {
if (flag) {
flag = false;
if (num == ol.children.length) {
ul.style.left = 0 + 'px';
num = 0;
}
num++;
simpleflash(ul, -num * target, 10, 5, function() {
flag = true; //动画函数执行完毕,再恢复控制变量
});
circle++;
if (circle == ol.children.length) {
circle = 0;
}
circleChange();
}
});
left.addEventListener('click', function() {
if (flag) {
flag = false;
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * target + 'px';
}
num--;
simpleflash(ul, -num * target, 10, 5, function() {
flag = true;
});
circle--;
if (circle < 0) {
circle = ol.children.length - 1;
}
circleChange();
}
});
function circleChange() {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
}
//自动播放
var timer = setInterval(function() {
right.click();
}, 5000);
返回顶部
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
window.scroll(0,0);
3.添加动画函数
//返回顶部
goBack.addEventListener('click', function() {
//1.
// document.body.scrollTop = 0;
// document.documentElement.scrollTop = 0;
//2.
// window.scroll(0, 0);
//3.
goTop(window, 0, 10, 15);
});
function goTop(obj, target, step, time, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var adv = (target - window.pageYOffset) / step; //减速
adv = adv > 0 ? Math.ceil(adv) : Math.floor(adv); //前进上取整,后退下取整
if (window.pageYOffset == target) {
clearInterval(obj.timer);
callback && callback();
}
window.scroll(0, window.pageYOffset + adv);
},
time);
};