运动的本质——>物体的状态发生连续性的变化
<divstyle="height:100px; width:100px; background: orange; position:absolute; left:0px; top: 0px;">div>
<button style="position: absolute; left:0px; top:150px;">runbutton>
<span style="width:1px; height:100px; background:black; position:absolute; left:300px; top:0px;"> span>
<script>
var oDiv = document.getElementsByTagName('div')[0],
oBtn = document.getElementsByTagName('button')[0],
iSpeed = 10, //控制速度
timer;
oBtn.onclick = function () {
startMove(oDiv);
}
function startMove (obj) {
clearInterval(timer); //开启定时器之前,先把上一个定时器清除
timer = setInterval(function () {
obj.style.left = obj.offsetLeft + iSpeed + 'px';
},30)
}
script>
function startMove (obj) {
clearInterval(timer);
timer = setInterval(function () {
if(obj.offsetLeft === 300) { //判断如果到达300的位置,就停止运动
clearInterval(timer);
}else{
obj.style.left = obj.offsetLeft + iSpeed + 'px';
}
},30)
}
当iSpeed不被300整除时,让方块停到300
function startMove (obj) {
clearInterval(timer);
timer = setInterval(function () {
if(obj.offsetLeft >= 300) { //判断如果到达300的位置,就停止运动
clearInterval(timer);
obj.style.left = '300px'; //超过后,让方块回来一点点,正好停在300位置
}else{
obj.style.left = obj.offsetLeft + iSpeed + 'px';
}
},30)
}
或者
function startMove (obj) {
clearInterval(timer);
timer = setInterval(function () {
if(300 - obj.offsetLeft < iSpeed) { //判断如果终点和方块位置的差小于步长,就停止定时器;
clearInterval(timer);
obj.style.left = '300px';
}else{
obj.style.left = obj.offsetLeft + iSpeed + 'px';
}
},30)
}
function startMove (obj) {
clearInterval(timer);
if(obj.offsetLeft > 300) {
iSpeed = -8; //如果方块在终点右侧,则速度为负
}else{
iSpeed = 8; //如果方块在终点左侧,则速度为正
}
timer = setInterval(function () {
if(Math.abs(300 - obj.offsetLeft) < Math.abs(iSpeed)) { //判断方块与终点的差,是否小于步长
clearInterval(timer);
obj.style.left = '300px';
}else{
obj.style.left = obj.offsetLeft + iSpeed + 'px';
}
},30)
}
缓冲运动
function startMove (obj) {
clearInterval(timer);
timer = setInterval(function () {
iSpeed = (300 - obj.offsetLeft) / 7;
console.log(iSpeed); //最后会在0.14左右无限循环
obj.style.left = obj.offsetLeft + iSpeed + 'px';
},30)
}
offsetLeft是向下取整的,所以加上的iSpeed如果小于1;那么就永远无法到达300位置,永远停留在299的位置上;
所以需要给iSpeed判断;
function startMove (obj) {
clearInterval(timer);
timer = setInterval(function () {
iSpeed = (300 - obj.offsetLeft) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
//如果方块在左侧;则iSpeed大于0,向上取整。
//如果方块在右侧;则iSpeed小于0,向下取整。
if(obj.offsetLeft === 300) {
clearInterval(timer)
}else {
obj.style.left = obj.offsetLeft + iSpeed + 'px';
}
},30)
}
var oDivWrapper = document.getElementsByTagName('div')[0],
timer = null;
oDivWrapper.onmouseenter = function () {
startMove(this, 0); //鼠标移入弹出
}
oDivWrapper.onmouseleave = function () {
startMove(this, -400); //鼠标移出弹回
}
function startMove (obj,target) { //target为目标点
clearInterval(timer);
var iSpeed;
timer = setInterval(function () {
iSpeed = (target - obj.offsetLeft) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if(obj.offsetLeft === target) {
clearInterval(timer);
}else {
obj.style.left = obj.offsetLeft + iSpeed + 'px';
}
},30)
}
function getStyle(obj, attr) {
if(obj.currentStyle) {
return obj.currentStyle[attr];
}else{
return window.getComputedStyle(obj, false)[attr];
}
}
<div style="width:100px;height:100px;background:red;opacity:0.9">div>
<script>
console.log(getStyle(oDiv, 'width'), typeof(getStyle(oDiv, 'width')));
// 100px string
console.log(getStyle(oDiv, 'opacity'), typeof(getStyle(oDiv, 'opacity')));
// 0.9 string
console.log(parseInt(getStyle(oDiv, 'width')), typeof(getStyle(oDiv, 'width')));
// 100 "string"
console.log(parseFloat(getStyle(oDiv, 'opacity')), typeof(getStyle(oDiv, 'opacity')));
// 0.9 "string"
script>
<div style="width:100px;height:100px;background:red;opacity:0.9">div>
<script>
var oDiv = document.getElementsByTagName('div')[0];
var timer = null;
function getStyle(obj, attr) {
if(obj.currentStyle) {
return obj.currentStyle[attr];
}else{
return window.getComputedStyle(obj, false)[attr];
}
}
function startMove(obj, target) {
clearInterval(timer);
var iSpeed;
timer = setInterval(function () {
iSpeed = (target - getStyle(obj, 'opacity'));
//target<= 1; opacite <= 1;
//所以,iSpeed取整之后,不是 +1 就是 0 或者 -1;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
obj.style.opacity = parseFloat(getStyle(obj, 'opacity')) + iSpeed;
//opacity加上 -1 再向下取整是 -1;而opacity的最小值是0,这时target - opacity的值为正,iSpeed的值就为1,所以,对象的透明度在0与1之间来回变化
}, 30)
}
startMove(oDiv, 0.5)
script>
opacity加上 -1 再向下取整是 -1;而opacity的最小值是0,这时target - opacity的值为正,iSpeed的值就为1,所以,对象的透明度在0与1之间来回变化;
解决方法,把数据扩大100倍,最后再/100;
function startMove(obj, target) {
clearInterval(timer);
var iSpeed,
iCur; //当前值
timer = setInterval(function () {
iCur = getStyle(obj, 'opacity') * 100;
iSpeed = (target - iCur) / 7;
//当前值扩大了100倍,这里的target(目标值)也要扩大100倍
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if(iCur == target) {
clearInterval(timer);
}else{
obj.style.opacity = (iCur + iSpeed) / 100;
}
}, 30)
}
oDiv.onclick = function () {
startMove(oDiv, 50);
}
var oDivArray = document.getElementsByTagName('div');
var timer = null;
for(var i = 0; i < oDivArray.length; i++) {
oDivArray[i].onmouseenter = function () {
startMove(this, 400); //鼠标移入改变当前对象宽度
}
oDivArray[i].onmouseleave = function () {
startMove(this, 100); //鼠标移出,把当前的宽度变回100
}
}
function startMove (obj,target) {
clearInterval(timer);
var iSpeed;
timer = setInterval(function () {
iSpeed = (target - obj.offsetWidth) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if(obj.offsetWidth === target) {
clearInterval(timer);
}else {
obj.style.width = obj.offsetWidth + iSpeed + 'px';
}
},30)
}
因为都在一个定时器里面,所以,鼠标快速移动时,上一个定时器还没有执行完,下一个定时器就开启了;在开启下一个定时器时,又把上一个定时器删除了,所以上一个对象就不能恢复到100了
解决方法
把定时器变成每一个对象的自身属性;清理时也清除自身的这个属性
function startMove (obj,target) {
clearInterval(obj.timer);
var iSpeed;
obj.timer = setInterval(function () {
iSpeed = (target - obj.offsetWidth) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if(obj.offsetWidth === target) {
clearInterval(obj.timer);
}else {
obj.style.width = obj.offsetWidth + iSpeed + 'px';
}
},30)
}
oDivArray[0].onclick = function () {
startMove(this, 400, 'width');
}
oDivArray[1].onclick = function () {
startMove(this, 400, 'height');
}
oDivArray[2].onclick = function () {
startMove(this, 50, 'opacity');
}
oDivArray[3].onclick = function () {
startMove(this, 10, 'borderWidth');
}
function startMove (obj, target, attr) {
clearInterval(obj.timer);
var iSpeed;
obj.timer = setInterval(function () {
if(attr == 'opacity') {
iCur = parseFloat(getStyle(obj, attr)) * 100;
}else {
iCur = parseInt(getStyle(obj, attr));
}
iSpeed = (target - iCur) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if(iCur === target) {
clearInterval(obj.timer);
}else {
if(attr == 'opacity') {
obj.style.opacity = (iCur + iSpeed) / 100;
}else {
obj.style[attr] = iCur + iSpeed + 'px';
}
}
},30)
}
var oDivArray = document.getElementsByTagName('div');
var timer = null;
var targetObj = {
width: 400,
height: 400,
opacity: 50,
left: 300,
top: 200
}
oDivArray[0].onclick = function () {
startMove(this, targetObj, function () {
startMove(oDivArray[1], targetObj);
});
}
function getStyle(obj, attr) {
if(obj.currentStyle) {
return obj.currentStyle[attr];
}else{
return window.getComputedStyle(obj, false)[attr];
}
}
function startMove(obj, json, callback) {
clearInterval(obj.timer);
var iSpeed,
iCur;
obj.timer = setInterval(function () {
var bStop = true;
for(var attr in json) {
if(attr == 'opacity') {
iCur = parseFloat(getStyle(obj, attr)) * 100;
}else {
iCur = parseFloat(getStyle(obj, attr));
}
iSpeed = (json[attr] - iCur) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if(attr == 'opacity') {
obj.style.opacity = (iCur + iSpeed) / 100;
}else {
obj.style[attr] = iCur + iSpeed + 'px';
}
if(iCur != json[attr]) {
bStop = false;
}
if(bStop) {
clearInterval(obj.timer);
typeof callback == 'function' ? callback() : ''; //判断参数是否是函数,是就执行(链式调用);
}
}
}, 30)
}