• 用队列模拟jquery的动画算法


    Aaron最近疯狂的爱上了算法研究,估计又要死伤不少脑细胞了,我喜欢捡现成的,可以省些力气。发现他写的一段源码,运行一下,还蛮好玩的,于是拿来分析一下,一来吸收下里边的营养,二来加深一下源码学习的功力。话说这源码还真是提高js内功的一大秘决,不信,就和我一起来品味一下吧。

    //立即执行函数,没有什么好说的。看下面演示
    /**
    (function($){
        //此处的$会由后面紧跟的立即执行函数的返回值提供
    })(function(){
        //这个函数运行的结果就是$啦
        return aQuery
    }())    
    
    */
    (function($) {
    
        window.$ = $;
    
    })(function() {
    
        //用来匹配ID字符串
        //(?:表示这里不分组) ,参考正则的内容
        //不过我个人认为把*改成+号会更好,因为#后至少要一个字符吧
        var rquickExpr = /^(?:#([w-]*))$/;
        //一看便是jquery的重度患者
        function aQuery(selector) {
            return new aQuery.fn.init(selector);
        }
    
        /**
         * 动画 
         * @return {[type]} [description]
         */
        var animation = function() {
    
            var self = {};
            var Queue = []; //动画队列
            var fireing = false //动画锁
            var first = true; //通过add接口触发
    
            var getStyle = function(obj, attr) {
                return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr];
            }
            //这里边都是具体的动画效果,没有什么难懂的
            var makeAnim = function(element, options, func) {
                var width = options.width
                    //包装了具体的执行算法
                    //css3
                    //setTimeout
                element.style.webkitTransitionDuration = '2000ms';
                element.style.webkitTransform = 'translate3d(' + width + 'px,0,0)';
    
                //监听动画完结
                element.addEventListener('webkitTransitionEnd', function() {
                    func()
                });
            }
    
            var _fire = function() {
                //加入动画正在触发
                if (!fireing) {
                    var onceRun = Queue.shift();
                    if (onceRun) {
                        //防止重复触发
                        fireing = true;
                        //next
                        onceRun(function() {
                            fireing = false;
                            //这里很巧妙的产生了连环调用的效果
                            _fire();
                        });
                    } else {
                        fireing = true;
                    }
                }
            }
    
            return self = {
                //增加队列
                add: function(element, options) {
                    //这里是整个算法的关键
                    //相当于往数组中添加一个函数
                    //[function(func){},...]
                    //也就是_fire中的onceRun方法,func也就是在那时传进去的。
                    //在Aaron的编程中很喜欢用这种技巧,比如预编译什么的。
                    Queue.push(function(func) {
                        makeAnim(element, options, func);
                    });
    
                    //如果有一个队列立刻触发动画
                    if (first && Queue.length) {
                        //这个开关很好的起到了控制后面添加的元素进行排队的作用
                        first = false;
                        //这里等价于直接运行_fire();
                        //Aaron喜欢装A,故意添加一个self.fire出来,或许他是深谋远虑
                        self.fire();
                    }
                },
                //触发
                fire: function() {
                    _fire();
                }
            }
        }();
    
    
        aQuery.fn = aQuery.prototype = {
            run: function(options) {
                animation.add(this.element, options);
                return this;
            }
        }
    
        var init = aQuery.fn.init = function(selector) {
            var match = rquickExpr.exec(selector);
            var element = document.getElementById(match[1])
            this.element = element;
            return this;
        }
        //差点小看了这一行代码
        //jquery的样子学的不错
        //直接aQuery.fn.init = aQuery.fn不是更好?
        //多一个init变量无非是想减少查询罢了,优化的思想无处不在。
        init.prototype = aQuery.fn;
    
        return aQuery;
    }());
    
    
    //dom
    var oDiv = document.getElementById('div1');
     
    //调用
    oDiv.onclick = function() {
    
        $('#div1').run({
            'width': '500'
        }).run({
            'width': '300'
        }).run({
            'width': '1000'
        });
    };

    附上html就可以自己调式了。要记得用chrome浏览哦。

    <div id="div1" style="100px;height:50px;background:red;cursor:pointer;color:#fff;text-align:center;line-height:50px;" data-mce-style=" 100px; height: 50px; background: red; cursor: pointer; color: #fff; text-align: center; line-height: 50px;">点击</div>

    演示地址:这个就不演示了。

  • 相关阅读:
    Ajax Bootstrap JSP .jsp JS .js DOM 概念
    CSS相关
    linux下python的tab自动补全功能:readline模块和ipython的安装
    python小技巧
    python中的值传递和引用传递(可变对象与不可变对象)也就是赋值的原理-python全部是引用传递
    Sql server 编写99乘法表
    消息对话框 MessageBoxButtons
    union与union all的用法给区别
    主要的窗体控件的概述
    窗体的常用方法和事件
  • 原文地址:https://www.cnblogs.com/afrog/p/4227523.html
Copyright © 2020-2023  润新知