The space is completely displaced by the absolute positioning of CSS. Before starting, let's practice the recursive usage of setTimeout (used to simulate setInterval).
function text(el){
var node = (typeof el == "string")? document.getElementById(el) : el;
var i = 0;
var repeat = function(){
setTimeout(function(){
node .innerHTML = "
" i "
";
i ;
if(i <= 100){
setTimeout(arguments.callee, 100);
}
},100)
}
repeat();
}
Let’s try the simplest fade-in effect, which is to change the node.innerHTML line into the transparency setting.
function fadeIn(el){
var node = (typeof el == "string")? document.getElementById(el) : el;
var i = 0;
var fade = function(){
setTimeout(function(){
! "v1"? (node.style.filter="alpha(opacity=" i ")"): (node.style.opacity = i / 100);
i ;
if(i <= 100 ){
setTimeout(arguments.callee, 100);
}
},100)
}
fade();
}
But This is not perfect, because IE's filter may not work in IE7, and we must use zoom=1 to activate hasLayout. Let's extend it by adding some customizable parameters. The comments are already very detailed. If you don’t understand, just ask me in the message.
function opacity(el){
//required Optional parameters
var node = (typeof el == "string")? document.getElementById(el) : el,
//Optional parameters
options = arguments[1] || {},
//Duration of change
duration = options.duration || 1.0,
//Transparency at the beginning
from = options.from || 0.0,
//Transparency at the end
to = options.to || 0.5,
operation = 1,
init = 0;
if(to - from < 0){
operation = -1,
init = 1;
}
//Internal parameters
//Interval time between setTimeout executions, unit milliseconds
var frequency = 100,
//Suppose the number of repeated calls
count = duration * 1000 / frequency,
// Calculate the increment of each transparency
detal = Math.abs(to - from) /count,
// Number of ongoing operations
i = 0 ;
var main = function(){
setTimeout(function(){
if(! "v1"){
if(node.currentStyle.hasLayout) node.style.zoom = 1; //Prevent filter failure
node.style.filter="alpha(opacity=" (init * 100 operation * detal * i * 100).toFixed(1) ")"
}else{
node.style.opacity = (init operation * detal * i).toFixed(3)
}
node.innerHTML = (init operation * detal * i).toFixed(3)
i ;
if(i <= count){
setTimeout(arguments.callee, frequency);
}
},frequency)
}
main();
}
Effect demonstration:
]
But the above is not perfect, there is a bug. We use the short-circuit operator to decide whether to use the default parameters or the parameters we pass in, but in javascript, the number 0 or even 0.0 will automatically convert to false. So in the first example, if we pass 0 in to, it will never use this 0, but the default 0.5. The solution is to make it the string "0". In addition, the parameter i is not necessary. We can omit it and use count to be responsible for all loops, but in this case, our thinking will be reversed. It turns out to be an addition, we want to change it to a subtraction.
The code is as follows:<script>
function opacity(el){
//必选参数
var node = (typeof el == "string")? document.getElementById(el) : el,
//可选参数
options = arguments[1] || {},
//变化的持续时间
duration = options.duration || 1.0,
//开始时透明度
from = options.from || 0.0 ,
//结束时透明度
to = options.to || 0.5,
operation = 1,
init = 0;
if(to - from < 0){
operation = -1,
init = 1;
}
//内部参数
//setTimeout执行的间隔时间,单位毫秒
var frequency = 100,
//设算重复调用的次数
count = duration * 1000 / frequency,
// 设算每次透明度的递增量
detal = Math.abs(to - from) /count,
// 正在进行的次数
i = 0;
var main = function(){
setTimeout(function(){
if(!+"\v1"){
if(node.currentStyle.hasLayout) node.style.zoom = 1;//防止滤镜失效
node.style.filter="alpha(opacity="+ (init * 100 + operation * detal * i * 100).toFixed(1) +")"
}else{
node.style.opacity = (init + operation * detal * i).toFixed(3)
}
node.innerHTML = (init + operation * detal * i).toFixed(3)
i++;
if(i <= count){
setTimeout(arguments.callee, frequency);
}
},frequency)
}
main();
}
</script>
function opacity(el){
//必选参数
var node = (typeof el == "string")? document.getElementById(el) : el,
//可选参数
options = arguments[1] || {},
//变化的持续时间
duration = options.duration || 1.0,
//开始时透明度
from = options.from || 0.0 ,
//结束时透明度
to = (options.to && options.to + "") || 0.5,
operation = -1,
init = 1;
if(to - from < 0){
operation = 1,
init = 0;
}
//内部参数
//setTimeout执行的时间,单位
var frequency = 100,
//设算重复调用的次数
count = duration * 1000 / frequency,
// 设算每次透明度的递增量
detal = operation * Math.abs(to - from) /count;
var main = function(){
setTimeout(function(){
if(!+"\v1"){
if(node.currentStyle.hasLayout) node.style.zoom = 1;//防止滤镜失效
node.style.filter="alpha(opacity="+ (init * 100 + detal * count * 100).toFixed(1) +")"
}else{
node.style.opacity = (init + detal * count).toFixed(3)
}
count--;
if(count + 1){
setTimeout(arguments.callee, frequency);
}
},frequency)
}
main();
}
进一步优化,利用原型共享方法。
function Opacity(el){
var node = (typeof el == "string")? document.getElementById(el) : el,
options = arguments[1] || {},
duration = options.duration || 1.0,
from = options.from || 0.0 ,
to = (options.to && options.to + "") || 0.5,
operation = -1,
init = 1;
if(to - from < 0){
operation = 1,
init = 0;
}
var frequency = 100,
count = duration * 1000 / frequency,
detal = operation * Math.abs(to - from) /count;
this.main(node,init,detal,count,frequency);
}
Opacity.prototype = {
main : function(node,init,detal,count,frequency){
setTimeout(function(){
if(!+"\v1"){
if(node.currentStyle.hasLayout) node.style.zoom = 1;//防止滤镜失效
node.style.filter="alpha(opacity="+ (init * 100 + detal * count * 100).toFixed(1) +")"
}else{
node.style.opacity = (init + detal * count).toFixed(3)
}
node.innerHTML = (init + detal * count).toFixed(3)
count--;
if(count + 1){
setTimeout(arguments.callee, frequency);
}
},frequency)
}
}
演示代码: