1. 潜在问题:目标值不是整数时
<html>
<head>
<title>title>
<style type="text/css">
#div1 {
width: 100px;
height: 100px;
background: red;
position: absolute;
left: 0;
top: 50px;
}
#div2 {
width: 1px;
height: 300px;
position: absolute;
left: 300px;
top: 0;
background: black;
}
style>
head>
<body>
<div id="div1">div>
<div id="div2">div>
<input type="button" value="Start" onclick="startMove()" />
<script type="text/javascript">
var oDiv = document.getElementById('div1');
function startMove() {
setInterval(function() {
//随着距离的减小,速度也越来越小,符合缓冲的要求,用距离(时刻变化)的十分之一
var speed = (300 - oDiv.offsetLeft) / 10;
oDiv.style.left = oDiv.offsetLeft + speed + 'px';
document.title = oDiv.offsetLeft + ', ' + speed;
}, 30);
}
script>
body>
html>
Math.ceil(3.2) ==> 4
Math.ceil(-9.7) ==> -9
Math.floor(5.98) ==> 5
function startMove() {
setInterval(function() {
//随着距离的减小,速度也越来越小,符合缓冲的要求,用距离(时刻变化)的十分之一
var speed = (300 - oDiv.offsetLeft) / 10;
speed = Math.ceil(speed);//划重点
oDiv.style.left = oDiv.offsetLeft + speed + 'px';
document.title = oDiv.offsetLeft + ', ' + speed;
}, 30);
}
这样就完了吗?没有!如果物体左移,也就是比如把div1的left的初始left由0 –> 600,那么,依旧不能分毫无差,最后看title为“309, 0”,实际上,速度为-0.9,(下一刻向着目标308.1px的位置移动),此时Math.ceil()已经不好用了,得用Math.floor();
#div1 {
width: 100px;
height: 100px;
background: red;
position: absolute;
left: 600px;/*0 --> 600*/
top: 50px;
}
function startMove() {
setInterval(function() {
var speed = (300 - oDiv.offsetLeft) / 10;
speed = Math.floor(speed);//划重点
oDiv.style.left = oDiv.offsetLeft + speed + 'px';
document.title = oDiv.offsetLeft + ', ' + speed;
}, 30);
}
offsetWidth = width + border + padding;
offsetWidth = height + border + padding;
offsetWidth = width + border + padding;
function startMove() {
setInterval(function() {
var speed = (300 - oDiv.offsetLeft) / 10;
speed = speed > 0 ? Math.ceil(speed) : Match.floor(speed);
oDiv.style.left = oDiv.offsetLeft + speed + 'px';
document.title = oDiv.offsetLeft + ', ' + speed;
}, 30);
}
总结:但凡是用了缓冲运动的一定要记得速度取整,缓冲也就是速度不停的变化。
注意几个概念:
offsetWidth = width + border + padding;
offsetHeight = width + border + padding;
document.documentElement.scrollHeight:
内容可视区域的高度,真正展示网页内容的高度,客户端的界面要跑除,如果你用鼠标调节浏览器窗口的大小,那么这个值会变化。
document.documentElement.scrollHeight:就是3500px,上面已经设置了
网页被卷去的高:document.body.scrollTop
兼容:
var top = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
综上所述:
在我们要获取文档实际高度时,最好用document.documentElement.scrollHeight
在我们要获取视口实际高度时,用document.documentElement.clientHeight
<html>
<head>
<title>title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#div1 {
width: 100px;
height: 150px;
background: red;
position: absolute;
bottom: 0;
right: 0;
border: 3px solid blue;
padding: 20px;
}
style>
head>
<body style="height: 3500px;">
<div id="div1">div>
<div id="div2">div>
<script type="text/javascript">
window.onscroll = function() {
var oDiv = document.getElementById('div1');
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
oDiv.style.top = document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop + 'px';
};
script>
body>
html>
<html>
<head>
<title>title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#div1 {
width: 100px;
height: 150px;
background: red;
position: absolute;
bottom: 0;
right: 0;
border: 3px solid blue;
padding: 20px;
}
style>
head>
<body style="height: 3500px;">
<div id="div1">div>
<div id="div2">div>
<script type="text/javascript">
window.onscroll = function() {
var oDiv = document.getElementById('div1');
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
//oDiv.style.top = document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop + 'px';
startMove(document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop);
};
var timer = null;
function startMove(iTarget) {
var oDiv = document.getElementById('div1');
clearInterval(timer);
timer = setInterval(function() {
var speed = (iTarget - oDiv.offsetTop)/6;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (oDiv.offsetTop == iTarget) {
clearInterval(timer);
} else {
oDiv.style.top = oDiv.offsetTop + speed + 'px';
}
}, 30);
}
script>
body>
html>
不同上边案例悬浮在右下角,而是‘fix’到右边正中间位置
<html>
<head>
<title>title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#div1 {
width: 100px;
height: 150px;
background: red;
position: absolute;
bottom: 0;
right: 0;
border: 3px solid blue;
padding: 20px;
}
style>
head>
<body style="height: 3500px;">
<div id="div1">div>
<div id="div2">div>
<script type="text/javascript">
window.onscroll = function() {
var oDiv = document.getElementById('div1');
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
//其实仅仅就是参数iTarget的计算变了一下
startMove((document.documentElement.clientHeight - oDiv.offsetHeight) / 2 + scrollTop);
};
var timer = null;
function startMove(iTarget) {
var oDiv = document.getElementById('div1');
clearInterval(timer);
timer = setInterval(function() {
var speed = (iTarget - oDiv.offsetTop)/6;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (oDiv.offsetTop == iTarget) {
clearInterval(timer);
} else {
oDiv.style.top = oDiv.offsetTop + speed + 'px';
}
}, 30);
}
script>
body>
html>
代码写完了,发现红色div在右边中间以很小的振幅在不同的抖动,问题就出在除以2这里,除以2就可能出现小数的可能性
startMove((document.documentElement.clientHeight - oDiv.offsetHeight) / 2 + scrollTop);
改为:
startMove(parseInt(document.documentElement.clientHeight - oDiv.offsetHeight) / 2 + scrollTop));