zoukankan      html  css  js  c++  java
  • Javascript动画系列之 —— lightbox实现(二)

      上次帖子里详细描述了lightbox实现思路,本想将整个原生的lightbox源码放出来,但是觉得留点思考的余地更好。

      本文中就贴上淡入淡出和滑动的JS原生代码,通过测试,能兼容IE8、Firefox、Chrome。

    function bind(fn, context){  //函数绑定,传递context上下文
        var args = Array.prototype.slice.call(arguments, 2);
        return function(){
            var innerArgs = Array.prototype.slice.call(arguments);
            var finalArgs = args.concat(innerArgs);  //柯里化参数
            return fn.apply(context, finalArgs);
        };
    }
    var addEvent = function(ele, event, fn){  //添加事件兼容
        ele.addEventListener ? ele.addEventListener(event, fn, false) :
        ele.attachEvent ? ele.attachEvent("on" + event, fn) : (ele["on" + event] = fn);
    };
    var animation = {
        config: {    //参数
            interval: 17,
            show: true,
            distance: 0,
            distanceW: 0                
        },
        calculate: function(strSpeed, height, width){    //几种模式不同的算法
            var speed = this.speedFn(strSpeed),
                i = this.config.interval;
            return typeof height === "undefined" && typeof width === "undefined" ?
            {
                frames: (speed - 0) / i,
                step: i / (speed - 0)
            } : {
                frames: (speed - 0) / i,
                step: i * height / (speed - 0),
                stepw: i * width / (speed - 0)
            }
        },
        trim: function(str){    //去掉两头空格,测试过速度相比其他trim方法快很多
            //return str.replace(/^\s*/, '').replace(/\s*$/, '');
            return str.replace(/^\s*|\s*$/, '');
        },
        speedFn: function(strSpeed){
            strSpeed = (this.trim(strSpeed)).toLowerCase();
            switch(strSpeed){
                case "fastest":
                    return 400;
                case "faster":
                    return 500;
                case "fast":
                    return 600;
                case "normal":
                    return 700;
                case "slow":
                    return 800;
                case "slower":
                    return 900;
                case "slowest":
                    return 1000;
                case "debug":
                    return 2000;
                default:
                    return 500;
            }
        },
        fadeOut: function(ele, strSpeed){                    
            var count = 0, c = this.config, s = ele.style,
                m$ = this.calculate(strSpeed);
            ele.currentStyle ? (s.filter = "alpha(opacity=100)") : s.opacity = 1;
    
            try{
                setTimeout(function(){
                    count++;
                    if(count > m$.frames){                            
                        ele.currentStyle ? (s.filter = "alpha(opacity=0)") : s.opacity = 0;
                    }else{
                        if(!ele.currentStyle){
                            s.opacity -= m$.step;
                        }else{
                            var f = parseFloat(ele.currentStyle.filter.match(/\d+/).toString());
                            f -= m$.step * 100;
                            s.filter = "alpha(opacity=" + f + ")";
                        }
                        setTimeout(arguments.callee, c.interval);
                    }
                }, c.interval); 
            }catch(ex){
                console.log("fadeOut error, " + ex.message);
            }
            c.show = false;
        },
        fadeIn: function(ele, strSpeed){
            var count = 0, c = this.config, s = ele.style,
                m$ = this.calculate(strSpeed);
            ele.currentStyle ? (s.filter = "alpha(opacity=0)") : s.opacity = 0;
    
            try{
                setTimeout(function(){
                    count++;
                    if(count > m$.frames){                            
                        ele.currentStyle ? (s.filter = "alpha(opacity=100)") : s.opacity = 1;
                    }else{
                        if(ele.currentStyle){
                            var f = parseFloat(ele.currentStyle.filter.match(/\d+/).toString());
                            f += m$.step * 100;
                            s.filter = "alpha(opacity=" + f + ")";
                        }else{
                            s.opacity = parseFloat(s.opacity) + m$.step;
                        }
                        setTimeout(arguments.callee, c.interval);
                    } 
                }, c.interval); 
            }catch(ex){
                console.log("fadeIn error, " + ex.message);
            }
            c.show = true;
        },
        fadeToggle: function(ele, strSpeed){    //淡入淡出切换
            var self = this;
            setTimeout(function(){                        
                self.config.show ? self.fadeOut(ele, strSpeed) : self.fadeIn(ele, strSpeed);
            }, 0);
        },
        slideOut: function(ele, strSpeed){
            var count = 0, u = "px", s = ele.style,
                c = this.config, cs = window.getComputedStyle ? window.getComputedStyle(ele) : ele.currentStyle,
                h = s.height = c.distance = parseFloat(cs["height"]),
                w = s.width = c.distanceW = parseFloat(cs["width"]);
    
            try{
                var    m$ = this.calculate(strSpeed, h, w);
                setTimeout(function(){
                    count++;
                    if(count > m$.frames || parseFloat(s.width) < m$.stepw || parseFloat(s.height) < m$.step){
                        s.height = 0;
                        s.width = 0;
                    }else{
                        s.height = (parseFloat(s.height) - m$.step) + u;
                        s.width = (parseFloat(s.width) - m$.stepw) + u;
                        setTimeout(arguments.callee, c.interval);
                    }
                }, c.interval); 
            }catch(ex)
            {
                console.log("slideOut error, " + ex.message);
            }
            c.show = false;
        },
        slideIn: function(ele, strSpeed){
            var count = 0, u = "px", s = ele.style,
                c = this.config, cs = window.getComputedStyle ? window.getComputedStyle(ele) : ele.currentStyle,
                h = c.distance,
                w = c.distanceW;
            try{
                var    m$ = this.calculate(strSpeed, h, w);
                setTimeout(function(){
                    count++;
                    if(count > m$.frames || parseFloat(s.width) > c.distanceW || parseFloat(s.height) > c.distance){                            
                        s.height = c.distance + u;
                        s.width = c.distanceW + u;
                    }else{
                        s.height = (parseFloat(s.height) + m$.step) + u;
                        s.width = (parseFloat(s.width) + m$.stepw) + u;
                        setTimeout(arguments.callee, c.interval);
                    }
                }, c.interval);
            }catch(ex){
                console.log("slideOut error, " + ex.message);
            }
            c.show = true; 
        },
        slideToggle: function(ele, strSpeed){
            this.config.show ? this.slideOut(ele, strSpeed) : this.slideIn(ele, strSpeed);
        }
    };
    
    addEvent(btn, "click", bind(animation.fadeToggle, animation, element, "normal"));  //最后调用

      代码还算清晰,主要的难点在于绑定的理解和兼容性的问题。

  • 相关阅读:
    进制转换
    01背包基础
    6-14 Inspector s Dilemma uva12118(欧拉道路)
    9-4 Unidirectional TSP uva116 (DP)
    8-4 奖品的价值 uva11491(贪心)
    9-1 A Spy in the Metro uva1025 城市里的间谍 (DP)
    8-3 Bits Equalizer uva12545
    8-2 Party Games uva1610 (贪心)
    自动发邮件功能
    窗口截图.py
  • 原文地址:https://www.cnblogs.com/moltboy/p/3045810.html
Copyright © 2011-2022 走看看