js闭包的奇芭应用
作者:毒药铁链西瓜刀
3365字节
点击:63133
回复:0
所属分类:无线互联网
创建时间:2013-08-31 10:03:46
最后修改时间:2013-08-31 10:03:46
我所在的团队做了一件很奇芭的事,就是在2个星期内做出一款人家花了一年时间做的toB产品,那啥,还是收费的。
这个产品其中有一个功能(只是其中一个小小的组成部分),就是提供一个编辑界面,通过这个界面客户可以制作一个简单的手机端网页,为了节省开发时间,我只设计了很简单的三种模块。
工程师把这个功能做完了,这时我意识到这实在是简单过分了,竞争对手的页面可是连图片轮播功能都提供了的。
于是我想到,如果我在编辑界面的输入框里直接加入js代码,是不是就可以实现很多特效了呢?这样一来,在不具备实际功能的情况下,我们仍然可以利用这个平台为客户制作出很炫的页面,并且这些页面还是可以在平台上进行管理的。
我尝试在文本框里写下了alert,果然工程师小伙没有做过滤,好了,我这样变态的想法看来是可以实现了。
既然如此,先来尝试弄个图片轮播吧。
于是我从网上copy了一段最简单的代码:
<script language =javascript >
var curIndex=0;
var timeInterval=5000;
var arr=new Array();
arr[0]="1.jpg";
arr[1]="2.jpg";
arr[2]="3.jpg";
arr[3]="4.jpg";
arr[4]="5.jpg";
arr[5]="6.jpg";
arr[6]="7.jpg";
setInterval(changeImg,timeInterval);
function changeImg()
{
var obj=document.getElementById("showpic");
if (curIndex==arr.length-1)
{
curIndex=0;
}
else
{
curIndex+=1;
}
obj.src="image/"+arr[curIndex];
}
</script>
<img src="image/1.jpg" width="427" height="219" id="showpic" />
我把这段代码稍微改了一下,放到文本框里一试,效果不错。
但这时我有点贪心,想在另一个模块里再放一个轮播“组件”。还没放下去,就发现一个问题,这段代码用了n个全局变量,这一放下去岂不是全乱套了吗?于是把这段代码用到的变量和函数名全部改掉。但是这样实在是太麻烦了,如果下次要用,岂不得再改一次?
好吧,我自己想出来的奇芭需求,只好靠自己想出更加奇芭的方案来解决。避免使用全局变量的最好办法,莫过于使用闭包。
<script>
~function(){
var curIndex=1;
var yes=Math.ceil(Math.random()*35)+'yes';
var timeInterval=2500;
document.write('<span id='+yes+'>'+arguments[0]+'</span>');
var me=arguments;
setInterval(function()
{
var obj=document.getElementById(yes);
if (curIndex==me.length-1)
{
curIndex=0;
}
else
{
curIndex+=1;
}
obj.innerText=me[curIndex];
}
,timeInterval);
}('毒药',
'铁链',
'西瓜刀','真倒霉')
</script>
嗯,说好的图片轮播,怎么变成文字轮播了?
唉,这主要是为了方便测试。
这段代码是一个立即执行的匿名函数。把它帖到任何地方,它都会立即写入一个span,并开始在span中自动切换文字显示。
使用者不必修改代码本身,只要在最后的括号里写入要轮播的文字即可。
基本上把它多次帖到一个页面中,这些文字轮播组件不会互相干扰。
之所以能做到这一点,是因为setInterval里的那个函数形成了一个闭包,形成了自己的独立作用域,把变量都封存起来了。
当然,这里美中不足的是,span的id我用了随机数来生成,随机数总是有一定重复可能性的。可是我目前真的是想不出其他办法在页面的任意位置生成一个不重复且可以随时调用的span,除非还是用到讨厌的全局变量。
也许你会想到用creatElement然后再appendChild,这样可以一开始就得到自己制造的span对象。但问题是,一段<script>并不知道自己在文档的哪个位置上,这样就无法准确地把span放到当前容器中。
另外,使用document.write还有一个严重的弊端,那就是如果编辑界面上实现了预览功能,它就会导致整个页面直接消失,只剩下刚写入的内容。因为预览实际上会造成在页面已经完成输出之后再次输出,而此时document.write会把原来的内容全部清空。
谁有好的主意?