您的位置:首页 > Web前端 > JavaScript

JS运动总结

2019-08-05 19:55 1081 查看

跟着视频学习了JS的运动基础以及相关的应用,总结了以下一套运动框架,可以直接调用。(以下所有项目调用的move.js文件均为此函数)

[code]/**
* 获取非行间样式,  兼容IE6--8
* @param styObj    属性对象
* @param name      属性名
* return string    样式值
*/
function getStyle(styObj,name) {

if(styObj.currentStyle){
return styObj.currentStyle[name];
}else {
return getComputedStyle(styObj,false)[name];
}
}

/**
* 运动函数
* @param obj           运动对象
* @param json          json属性数组
*                      json={ attr1:target1,attr2:target2 ......}
* @param fnElement     回调函数
*/
function startMoving(obj,json,fnElement) {

if(obj.timer != null)       // 多物体运动时,定时器各自工作,互不干扰
clearInterval(obj.timer);

obj.timer = setInterval(function () {
let stop = true;        // 假设所有的值都已到了

for(let attr in json){

let currVal = 0;  // 当前属性样式值
if(attr == "opacity"){
currVal = Math.round(parseFloat(getStyle(obj,attr))*100);
}else {
currVal = parseInt(getStyle(obj,attr));
}

let speed = (json[attr] - currVal) / 8; // 运动速度
speed = speed>0? Math.ceil(speed) : Math.floor(speed);  // 速度取整

// 判断当前值是否等于目标值,如果不等,说明还未到达运动停止条件
if(currVal != json[attr])
stop=false;

if(attr == "opacity"){
obj.filter = "alpha(opacity:"+(currVal + speed)+")";
obj.style.opacity = (currVal + speed) / 100;
}else {
obj.style[attr] = currVal + speed +"px";
}
}

// 如果stop==true,说明中间没有出现未到达情况
if(stop){
clearInterval(obj.timer);
if(fnElement) fnElement();
}
},30);
}

该框架可实现多个属性同时发生改变时的运用。需要注意的是,在开启定时器时,一定要先给每个对象都加入属于自己的定时器,这样当开启多个定时器时,才不会引起一系列不必要的问题。

运用运动框架,我写了几个简单的小案例,供参考学习和巩固。

案例1:

[code]<head>
<meta charset="UTF-8">
<title>JS运动--完美运动框架,多属性同时运动</title>
<style>
div{width: 100px;height: 100px;background-color: darkred;filter: alpha(opacity:30);opacity: 0.3;position: absolute;right: 0;bottom: 0}
</style>
</head>
<body>
<button id="btn">显示</button>
<div></div>

<script src="move.js"></script>
<script>
window.onload = function () {
let div = document.getElementsByTagName("div")[0];

let btn = document.getElementById("btn");
let flag=false; // 记录按钮是否被点击
btn.onclick = function () {

if(flag == false){
btn.innerHTML = "隐藏";

// 注意!!! 这种情况下会出现异常。
// 因为当width达到目标值后,程序认为已经运动结束了,就将定时器给关闭了,导致后面的效果无法运行
// 改进,使用 json 解决
startMoving(div,{width:110,height:400,opacity:100},function () {
console.info("完成了");
});

flag=true;
}else {
btn.innerHTML = "显示";
startMoving(div,{width:100,height:100,opacity:30});
flag=false;
}
}
}
</script>
</body>

 

案例2:实现类似于论坛发帖的效果,新消息显示在最前面,并添加从上往下的动画效果。

总结:在这个案例中,又把前面学过的DOM操作复习了遍。从创建子节点到追加和插入子节点,以及JS的运动函数。在实现的过程中,对于可变长的li高度问题,需要通过offsetHight来获取待插入节点的高,然后再设置其运动的距离。

我在写的过程中,最开始设置了li的宽度,然后高度设为了100%,这样导致了我在插入的时候出现了两个问题:

  1. 运动的过程变得很快,看起来就很生硬。而且当li设置了border-bottom时,插入时文字会最先全部出来,然后border-bottom才缓慢下来,这种现象在当ul里面没有li时,插入第一个li 体现最明显。
  2. 当我每次添加新内容,新内容和旧内容从上往下出来时,旧内容的背景是透明的,原因我还不是很明白。

针对出现的问题,后来我发现是宽高出了问题,不应该设置宽高,内容的宽高应该由padding撑开。对于这种自适应的,应该要注意这个问题,很关键!!!

[code]<head>
<meta charset="UTF-8">
<title>JS运动应用--论坛消息列表</title>
<style>
body,ul,ol,li,p,h1,h2,h3,h4,h5,h6,form,fieldset,table,td,img,div,dl,dt,dd,input{margin: 0; padding: 0;}
body{font-size: 12px;}
img{border: none;}
li{list-style: none;}
input,select,textarea{outline: none;}
textarea{resize: none;}
a{text-decoration: none;}

#message ul{width: 550px;height: 400px;overflow: hidden;border: 1px solid black;margin: 40px auto;}

/* 不设置li的宽高,内容由padding撑开 */
#message ul li{border-bottom: 1px dashed;padding:10px 20px 4px;overflow: hidden}
</style>
</head>
<body>
<div>
<textarea id="inform" cols="100" rows="10"></textarea>
<input id="btn" type="submit" value="回复">
</div>
<div id="message">
<ul></ul>
</div>

<script src="move.js"></script>
<script>
window.onload = function () {
let btn = document.getElementById("btn");
let inform = document.getElementById("inform");
let uls = document.getElementById("message").getElementsByTagName("ul")[0];

btn.onclick = function () {

// 获取文本框输入的内容
let message = inform.value;
inform.value="";

// 创建元素
let li = document.createElement("li");

li.innerHTML = message;

if(uls.children.length >0){
// 当前列表项插入到ul的第一个子节点前面
uls.insertBefore(li,uls.children[0]);
}else {
uls.appendChild(li);
}

// 获取li当前内容的高度
let liHeight = li.offsetHeight;

li.style.height = "0";

startMoving(li,{height:liHeight});
}
}
</script>
</body>

写在最后的话:

我在查阅资料的时候,发现了一个作者写的JS运动系列,里面的案例比我的更丰富一些,写得也确实比我的好。

https://www.geek-share.com/detail/2687957900.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: