JavaScript滚动条的制作
437
2013-3-3

效果演示

这个效果的制作是借助setTimeout的第三个参数。setTimeout/setInterval,这两个函数相信前端开发同学都很熟悉。它们在非IE(6-9)浏览器中还可以如下使用:

setTimeout(function(obj){
	alert(obj.a);
}, 2000, {a:1});

即传了第三个参数,第三个参数将作为回调函数的参数obj传入。在非IE浏览器中都弹出了1。这样有个好处,即解决了回调函数的执行上下文,比如要调用某个对象的某个方法,即可以通过参数把该对象传进去。

setTimeout(function(obj){
	obj.method();
}, 2000, obj);

上次看到一个setTimeout的一个用法:

	var arr = [1,9,2,8,3,7,4,6,4,5];
	for(var i = 0, len = arr.length; i < len; i++){
		setTimeout(function(x){
     		console.log(x);
    	},arr[i],arr[i]);
	}

虽然这个并不是什么好的用法,这里setTimeout的第三个参数主要得到了除IE外的系列浏览器的支持。

要让IE支持的话,可以按下面方法进行扩展:

(function(w){
    //ie传入第三个参数
    if(!+[1,]){//除IE外,!+[1,]都是返回false
        (function(overrideFn){
            w.setTimeout = overrideFn(w.setTimeout);
            w.setInterval = overrideFn(w.setInterval);
        })(function(originalFn){
            return function(code,delay){
                var args = Array.prototype.slice.call(arguments,2);
                return originalFn(function(){
                    if(typeof code == 'string'){
                        eval(code);
                    }else{
                        code.apply(this,args);
                    }
                },delay);
            }
        })
    }
})(window)

如果有第三个参数,某些情况下的调用就可以方便的处理回调函数中当前对象的问题,写起来好看点。扩展一下Function,增加一个延时调用(参考而已):

	function.prototype.delay = function(){
        var args = Array.prototype.slice.call(arguments,0);
        setTimeout(function(fn){
            fn.apply('',args.slice(1));
        },args[0],this);
    }
    var fn = function(x){
        alert(x)
    };
    fn.delay(1000,'xesam');

下面是模拟进度条的代码:

<script type="text/javascript">
    function Load(id,width){
        this.ele = document.getElementById(id);
        this.indicator = document.createElement('div');
        this.width = (width > 0 && width) || 300;
        this.init();
    }
    Load.prototype = {
        constructor:Load,
        init:function(){
            this.ele.style.width = this.width + 'px';
            this.ele.appendChild(this.indicator);
            var iStyle = this.indicator.style;
            iStyle.width = 0;
            iStyle.height = '100%';
            iStyle.background = '#ff5500';
        },
        start:function(){
            //this.init();
            this.loading();
        },
        loading:function(){
            this.timer = setTimeout(function(obj){
                var t = obj.indicator.data || 0;
                if(t < obj.width){
                    obj.indicator.style.width = t + 1 +'px';
                    obj.indicator.data = t + 1;
                    obj.loading();
                }else{
                    clearInterval(obj.timer);
                }
            },10,this);
        },
        stop:function(){
            clearTimeout(this.timer);
        }
    }
    var load_1 = new Load('loading',300);
    load_1.start();
</script>