关于缓动动画的JS代码封装:(支持来回运动)
缓动动画在书写的时候会存在一些问题,牵涉到向上取整和向下取整问题,这些问题的关于是由于offsetleft在取值的时候是采用四舍五入取整的策略,导致缓动动画在运动为末尾会陷入死循环,导致无法到达最终的目标位置,以及无法清除定时器。所以特别将缓动动画的封装代码展示出来以供后期使用:
//缓动动画封装
function animate(ele,target) {
//要用定时器,先清定时器
//一个萝卜一个坑儿,一个元素对应一个定时器
clearInterval(ele.timer);
//定义定时器
ele.timer = setInterval(function () {
//获取步长
//步长应该是越来越小的,缓动的算法。
var step = (target-ele.offsetLeft)/10;
//对步长进行二次加工(大于0向上取整,小于0项下取整)
step = step>0?Math.ceil(step):Math.floor(step);
//动画原理: 目标位置 = 当前位置 + 步长
ele.style.left = ele.offsetLeft + step + "px";
//检测缓动动画有没有停止
console.log(1);
if(Math.abs(target-ele.offsetLeft)<=Math.abs(step)){
//处理小数赋值
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},30);
}
关于匀速动画的JS代码封装:(支持来回运动)
function animate(ele,target){
//要用定时器,先清除定时器
//一个盒子只能有一个定时器,这样儿的话,不会和其他盒子出现定时器冲突
//而定时器本身讲成为盒子的一个属性
clearInterval(ele.timer);
//我们要求盒子既能向前又能向后,那么我们的步长就得有正有负
//目标值如果大于当前值取正,目标值如果小于当前值取负
var speed = target>ele.offsetLeft?10:-10;
ele.timer = setInterval(function () {
//在执行之前就获取当前值和目标值之差
var val = target - ele.offsetLeft;
ele.style.left = ele.offsetLeft + speed + "px";
//目标值和当前值只差如果小于步长,那么就不能在前进了
//因为步长有正有负,所有转换成绝对值来比较
if(Math.abs(val)<Math.abs(speed)){
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},30)
}
Scroll()方法的封装
scrollTop和scrollLeft是用来监测浏览器滑动范围(Y方向和X方向)的两个属性,但是各大浏览器对于这两个属性的支持程度不同,所以在使用时,要兼容各大浏览器
具体差别如下描述:
一、未声明 DTD(谷歌只认识他)
document.body.scrollTop
二、已经声明DTD(IE678只认识他)
document.documentElement.scrollTop
三、火狐/谷歌/ie9+以上支持的
window.pageYOffset
常见的兼容性写法:
var aaa = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
var aaa = document.documentElement.scrollTop + document.body.scrollTop;
为了检测网页是否声明DTD,引入了compatMode
document.compatMode === "BackCompat"
BackCompat 未声明
CSS1Compat 已经声明
注意大小写
借助Json,对该方法进行封装如下:
function scroll(){
//如果这个属性存在,那么返回值应该是0-无穷大
//如果没有返回值是undefined;
//只要判断不是undefined就可以调用此方法
//练习使用此种封装
if(window.pageYOffset !== undefined){
// var json = {
// "top": window.pageYOffset,
// "left": window.pageXOffset
// };
// return json;
return {
"top": window.pageYOffset,
"left": window.pageXOffset
};
}else if(document.compatMode === "CSS1Compat"){
return {
"top": document.documentElement.scrollTop,
"left": document.documentElement.scrollLeft
};
}else{
return {
"top": document.body.scrollTop,
"left": document.body.scrollLeft
};
}
//简单封装(实际工作使用)
// return {
// "top": window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop,
// "left": window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft
// }
}
另外:获取title、body、head、html标签
- document.title --- 文档标题;
- document.head --- 文档的头标签
- document.body --- 文档的body标签;
- document.documentElement --- 这个很重要
它表示文档的html标签, 也就是说,基本结构当中的html标签并不是通过document.html 去访问的,而是document.documentElement
JS楼层跳转小案例
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
*{
margin: 0px;
padding: 0px;
}
html,body{
height: 100%;
}
ul{
list-style: none;
height: 100%;
}
ul li{
height: 100%;
}
ol{
list-style: none;
position: fixed;
top: 80px;
left:50px;
}
ol li{
width: 50px;
height: 50px;
border:1px solid #000;
text-align: center;
line-height: 50px;
margin-top: -1px;
cursor: pointer;
}
</style>
<body>
<ul>
<li>鞋子区域</li>
<li>袜子区域</li>
<li>裤子区域</li>
<li>裙子区域</li>
<li>帽子区域</li>
</ul>
<ol>
<li>鞋子</li>
<li>袜子</li>
<li>裤子</li>
<li>裙子</li>
<li>帽子</li>
</ol>
<script src="animate.js"></script>
<script>
//需求:点击ol中的li,屏幕划定到对应的ul中的li的范围
//思路:还是利用window.scrollTo();利用缓动动画原理实现屏幕滑动
//步骤;
//0.获取元素
var ul=document.getElementsByTagName("ul")[0];
var ol=document.getElementsByTagName("ol")[0];
var ulLiArr=ul.children;
var olLiArr=ol.children;
var timer=null;
var target=0;
var leader=0;
//1.指定ul和ol中的li的背景色,对应的li背景色相同
//设置一个数组,里面装颜色,然后指定的颜色给数组中的指定元素
var arrColor=["pink","blue","yellow","orange","green"];
//利用for循环给两个数组中的元素上色
for (var i = 0; i < arrColor.length; i++) {
ulLiArr[i].style.backgroundColor=arrColor[i];
olLiArr[i].style.backgroundColor=arrColor[i];
//属性绑定索引值
olLiArr[i].index=i;
//2.老三步(并绑定事件)循环绑定
olLiArr[i].onclick=function () {
//*****获取目标位置
//获取索引值
target = ulLiArr[this.index].offsetTop;
//要用定时器,先清除定时器
clearInterval(timer);
//3.利用缓动动画原理实现屏幕滑动
timer=setInterval(function () {
//1.获取步长。
var step=(target-leader)/10;
//2.二次处理步长
step=step>0?Math.ceil(step):Math.floor(step);
//3.屏幕滑动
leader=leader+step;
window.scrollTo(0,leader);
//4.清除定时器
if(Math.abs(leader-target)<=Math.abs(step)){
window.scrollTo(0,target);
clearInterval(timer);
}
},25);
}
}
window.onscroll=function () {
//每次屏幕互动,把屏幕卷曲的头部复制给leader,模拟获取显示区域距离网页顶部的距离
leader=scroll().top;
document.title=leader;
}
</script>
</body>
</html>
其中引用的JS文件如下:
//缓动动画封装
function animate(ele,target) {
clearInterval(ele.timer);
ele.timer = setInterval(function () {
var step = (target-ele.offsetTop)/10;
step = step>0?Math.ceil(step):Math.floor(step);
ele.style.top = ele.offsetTop + step + "px";
console.log(1);
if(Math.abs(target-ele.offsetTop)<Math.abs(step)){
ele.style.top = target + "px";
clearInterval(ele.timer);
}
},25);
}
function scroll() { // 开始封装自己的scrollTop
if(window.pageYOffset != null) { // ie9+ 高版本浏览器
// 因为 window.pageYOffset 默认的是 0 所以这里需要判断
return {
left: window.pageXOffset,
top: window.pageYOffset
}
}
else if(document.compatMode === "CSS1Compat") { // 标准浏览器 来判断有没有声明DTD
return {
left: document.documentElement.scrollLeft,
top: document.documentElement.scrollTop
}
}
return { // 未声明 DTD
left: document.body.scrollLeft,
top: document.body.scrollTop
}
}
/**
* Created by Lenovo on 2016/9/2.
*/
/**
* 通过传递不同的参数获取不同的元素
* @param str
* @returns {*}
*/
function $(str){
var str1 = str.charAt(0);
if(str1==="#"){
return document.getElementById(str.slice(1));
}else if(str1 === "."){
return document.getElementsByClassName(str.slice(1));
}else{
return document.getElementsByTagName(str);
}
}
/**
* 功能:给定元素查找他的第一个元素子节点,并返回
* @param ele
* @returns {Element|*|Node}
*/
function getFirstNode(ele){
var node = ele.firstElementChild || ele.firstChild;
return node;
}
/**
* 功能:给定元素查找他的最后一个元素子节点,并返回
* @param ele
* @returns {Element|*|Node}
*/
function getLastNode(ele){
return ele.lastElementChild || ele.lastChild;
}
/**
* 功能:给定元素查找他的下一个元素兄弟节点,并返回
* @param ele
* @returns {Element|*|Node}
*/
function getNextNode(ele){
return ele.nextElementSibling || ele.nextSibling;
}
/**
* 功能:给定元素查找他的上一个兄弟元素节点,并返回
* @param ele
* @returns {Element|*|Node}
*/
function getPrevNode(ele){
return ele.previousElementSibling || ele.previousSibling;
}
/**
* 功能:给定元素和索引值查找指定索引值的兄弟元素节点,并返回
* @param ele 元素节点
* @param index 索引值
* @returns {*|HTMLElement}
*/
function getEleOfIndex(ele,index){
return ele.parentNode.children[index];
}
/**
* 功能:给定元素查找他的所有兄弟元素,并返回数组
* @param ele
* @returns {Array}
*/
function getAllSiblings(ele){
//定义一个新数组,装所有的兄弟元素,将来返回
var newArr = [];
var arr = ele.parentNode.children;
for(var i=0;i<arr.length;i++){
//判断,如果不是传递过来的元素本身,那么添加到新数组中。
if(arr[i]!==ele){
newArr.push(arr[i]);
}
}
return newArr;
}
效果如下所示:
效果图.gif
有一些bug,就是不方便滑动,需要优化
欢迎关注我的个人微信公众号,免费送计算机各种最新视频资源!你想象不到的精彩!
0.jpg
网友评论