透明特效是script.aculo.us提到的特效中最简单的特效之一。既然是特效,必须涉及时间与空间的概念。时间我们可以用setTimeout与setInterval,个人比较喜欢setTimeout,虽然它每次调用都重复注册,但可控性比较好。空间就全凭CSS的绝对定位实现位移了。在开始之前,我们练习一下setTimeout的递归用法(用来模拟setInterval)。
function text(el){
var node = ( typeof el == "string" )? document.getElementById(el) : el;
var i = 0;
var repeat = function (){
setTimeout( function (){
node.innerHTML = "<h1>" +i+ "</h1>" ;
i++;
if (i <= 100){
setTimeout(arguments.callee, 100);
}
},100)
}
repeat();
}
|
我们来试一下最简单的淡入特效,就是把node.innerHTML那一行改成透明度的设置。
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();
}
|
但是这样并不完美,因为IE的滤镜可能会在IE7中失效,我们必须要用zoom=1来激活hasLayout。我们再添加一些可制定参数扩充它。注释已经非常详细,不明白在留言里再问我吧。
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;
}
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();
}
|
< div class="text" onclick="opacity(this,{duration:4.0,from:0.0,to:1})"></ div >
< div class="text" onclick="opacity(this,{duration:4.0,from:1.0,to:0})"></ div >
|
但上面并不尽善尽美,有一个Bug。我们是通过短路运算符来决定是否使用默认参数还是我们传入的参数,但在javascript中,数字0甚至0.0都会自动转换为false。因此在第个例子,如果我们在to中传入0,它永远不会用到这个0,而是默认的0.5。解决方法让它变成字符串“0”。另,参数i也不是必须的,我们可以省去它,用count负责所有的循环,但这样一来,我们的思维就要逆过来想了。原来是加的,我们要变成减的。
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;
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)
}
}
|
< div class="text" onclick="new Opacity(this,{duration:4.0,from:0.0,to:1})"></ div >
< div class="text" onclick="new Opacity(this,{duration:4.0,from:1.0,to:0})"></ div >
|
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端