SimpleUI的更新。。。

SimpleUI终于更新了。。该项目目前托管在Google Code上。。地址是:https://simple-ui.googlecode.com/svn/trunk

首先看变化的方面。。。新的SimpleUI采用了单体模式编写代码。。核心机制并没有依赖jQuery。所有的组件采用面向对象方式编写。。并且提供了一个桥接到jQuery原型链上的一个函数。。。

新的核心参考了YUI和Dojo的模块化的机制。。。增加了一个声明类的函数,继承方式使用了拷贝继承!

比如如果我想为jQuery添加一个方法

Y.bridgeTojQuery("drag,simpleDrag",Y.dd.Drag)

调用的话

$("#drag").drag()
//或者
$("#drag").simpleDrag()

核心代码:

/**
 * author:xing
 * date:2011-06-21
 */
if (typeof Y == "undefined") {
    this.Y = {
        version: 0.6,
        //加载JS的路径
        baseJSPath: "js/",
        //加载CSS的路径
        baseCssPath: "../styles/",
        //存储已经加载的JS或者CSS模块
        moduleLoaded: {
            js: [],
            css: []
        }
    }
}
Y.mixin = $.extend;
Y.mixin(Y, {
    namespace: function(){
        var a = arguments, o = this, i = 0, j, d, arg;
        for (; i < a.length; i++) {
            arg = a[i];
            if (arg.indexOf(".")) {
                d = arg.split(".");
                for (j = (d[0] == 'Y') ? 1 : 0; j < d.length; j++) {
                    o[d[j]] = o[d[j]] || {};
                    o = o[d[j]];
                }
            }
            else {
                o[arg] = o[arg] || {};
            }
        }
        return o;
    },
    each: $.each,
    data: $.data,
    /**
     * 将一些属性或者方法添加到构造函数的原型链上
     * @param {function} constructor
     * @param {Object} prop
     */
    extend: function(constructor, prop){
        if (typeof constructor !== "function") {
            Y.log(constructor, "is not an valid constructor!");
        }
        else {
            Y.mixin(constructor.prototype, prop);
        }
    },
    /**
     * 向Y对象中添加一个方法
     * 如果定义一个构造函数请使用declare方法
     * @param {Object} modName
     * @param {Object} callback
     * <code>
     * 	Y.register("util.console",function(){
     * 		Y.log("console");
     *  });
     *  Y.util.console();//will print "console"
     * </code>
     */
    register: function(modName, callback){
        if (typeof callback == "function") {
            if (Y[modName]) {
                Y.log("override" + modName + "method");
            }
            if (modName.indexOf(".")) {
                var modNameArray = modName.split(".");
                if (modNameArray.length == 1) {
                    Y[modName] = callback;
                }
                else {
                    var s = Y.namespace(modNameArray.splice(0, modNameArray.length - 1).join(","));
                    s[modNameArray[modNameArray.length - 1]] = callback;
                }
            }
        }
        else {
            Y.log(callback, "is not an valid method");
        }
    },
    unregister: function(modName){
        Y[modName] = null;
        Y.log(modName + " has be setted null");
    },
    bridgeTojQuery: function(methodName, widget){
        var methodArray = methodName.split(",");
        Y.each(methodArray, function(i, n){
            $.fn[n] = function(config){
                return this.each(function(){
                    config = Y.mixin({}, config, {
                        node: this
                    });
                    new widget(config);
                });
            }
        });
    },
    /**
     * 辅助的输出函数,避免console在IE下导致脚本报错
     * @param {Object} obj
     * @param {Object} msg
     */
    log: function(obj, msg){
        if (console) {
            if (msg) {
                console.log(obj, msg);
            }
            else {
                console.log(obj);
            }
        }
    }
});
Y.mixin(Y, {
    /**
     * 定义一个构造函数
     * summary:要使用这个函数也必须实例化
     * @param {string} subClass 类的名称
     * @param {string||array} parentClass 继承的父类名称
     * @param {Object} prop 一些对象,将会被添加到subClass的原型链上,如果该subClass有父类将会被子类的属性或者方法覆盖掉
     * <code>
     * 	Y.declare("Hello",null,{
     * 		msg:"HelloWorld",
     * 		init:function(){
     * 			Y.log(this.msg);
     * 		}
     *  });
     *  var demo=new Y.Hello({
     *  	msg:"super"
     *  });
     *  //print super
     * </code>
     *
     * <code>
     * 	Y.declare("HelloWorld",Y.Hello,{
     *	otherMsg:"this is helloworld",
     *	init:function(){
     *		Y.log(this.otherMsg);
     *	}
     *	});
     * var test=new Y.HelloWorld();
     * //print HelloWorld,this is helloworld
     * </code>
     */
    declare: function(subClass, superClass, prop){
        var pro = prop;
        //crack the superClass
        if (superClass) {
            if (superClass instanceof Array) {
                Y.each(superClass, function(n){
                    pro = Y.mixin({}, n.prototype, pro);
                });
            }
            else {
                pro = Y.mixin({}, superClass.prototype, pro);
            }
        }
        if (subClass.indexOf(".")) {
            var modNameArray = subClass.split(".");
            if (modNameArray.length == 1) {
                Y[subClass] = function(){
                    var arg = arguments, s = this;
                    if (arg[0]) {
                        Y.each(arg[0], function(key, value){
                            s[key] = value;
                        });
                    }
                    this.init.call(this);
                }
                Y.extend(Y[subClass], pro);
            }
            else {
                var s = Y.namespace(modNameArray.splice(0, modNameArray.length - 1).join(","));
                s[modNameArray[modNameArray.length - 1]] = function(){
                    var arg = arguments, s = this;
                    if (arg[0]) {
                        Y.each(arg[0], function(key, value){
                            s[key] = value;
                        });
                    }
                    this.init.call(this);
                }
                Y.extend(s[modNameArray[modNameArray.length - 1]], pro);
            }
        }
        return Y;
    }
});
Y.namespace("Y.ui");
Y.mixin(Y, {
    _allModuleNum: 0,
    /**
     * 为了确保ui中的widget加载JS完毕而设计的函数,避免出现未加载完毕而执行依赖ui的代码
     * @param {function} callback
     */
    ready: function(callback){
        var self = this;
        setTimeout(function(){
            if (self._allModuleNum == 0) {
                if (typeof callback == "function") {
                    callback();
                }
            }
        }, 0);
    },
    /**
     * 向Y对象中添加一个widget
     * @param {string} modName
     * @param {object} prop
     * @param {Object} required
     * <code>
     * 	Y.add("Dialog",{
     * 		dialogTitle:"this is a dialogTitle",
     * 		init:function(){
     * 			Y.log(this.dialogTitle);
     * 		}
     *  },{
     *  	js:"jquery",
     *  	css:"dialog"
     *  });
     *  var d = new Y.ui.Dialog();
     *  //if jquery is loaded,will print "this is a dialogTitle"
     * </code>
     */
    add: function(modName, prop, required, superCls){
        //required is an array
        var isLoaded = false, self = this;
        if (required) {
          /*  var loadingJs;
            if (required.js) {
                loadingJs = required.js.split(",");
                Y.each(loadingJs, function(index, item){
                    self._loadJs(item);
                });
                setTimeout(function(){
                    if (self._allModuleNum == loadingJs.length) {
                        Y.declare(modName, superCls, prop);
                        self._allModuleNum = 0;
                    }
                }, 0);
            }*/
            if (required.css) {
                var loadingCss = required.css.split(",");
                Y.each(loadingCss, function(index, item){
                    self._loadCss(item);
                });
                //setTimeout(function(){
                   // Y.declare(modName, superCls, prop);
              //  }, 0);
            }
			Y.declare(modName, superCls, prop);
        }
        else {
            Y.declare(modName, superCls, prop);
        }
    },
    _loadJs: function(src, callback){
        if (src) {
            var isLoaded = this._isExsit(src), self = this;
            if (isLoaded) {
                self._allModuleNum++;
            }
            else {
                var script = document.createElement("script"), time;
                script.type = "text/javascript";
                script.src = Y.baseJsPath + src + ".js";
                document.getElementsByTagName("head")[0].appendChild(script);
                time = setTimeout(function(){
                    Y.log("can't load js from " + src, " are you sure the src that is correct?");
                    
                    script.parentNode.removeChild(script);
                }, 5000);
                script.onreadystatechange = script.onload = function(){
                    Y.log("loadSuccess" + src + ".js");
                    Y.moduleLoaded.js.push(src);
                    
                    self._allModuleNum++;
                    script.onreadystatechange = script.onload = null;
                    clearTimeout(time);
                }
            }
        }
    },
    _loadCss: function(src){
        if (src) {
            var isLoaded = this._isExsit(src);
            if (!isLoaded) {
                var link = document.createElement("link");
                link.rel = "stylesheet";
                link.href = Y.baseCssPath + src + ".css";
                link.type = "text/css";
                if (link.onload) {
                    link.onload = function(){
                        //do sth
                    }
                }
                else {
                    //do sth
                }
                document.getElementsByTagName("head")[0].appendChild(link);
                Y.moduleLoaded.css.push(src);
            }
        }
    },
    _isExsit: function(src, type){
        var compareModule = type == "js" ? Y.moduleLoaded.js : Y.moduleLoaded.css, isLoaded = false;
        Y.each(compareModule, function(index, item){
            if (item == src) {
                isLoaded = true;
                return false;
            }
        });
        return isLoaded;
    }
});

Y.namespace("util");
Y.mixin(Y.util, {
    formatString: function(str, obj){
        if (typeof str != "string") {
            Y.log(str, "is not a string");
            return Y;
        }
        if (obj) {
            for (var key in obj) {
                str = str.replace("{" + key + "}", obj[key]);
            }
            return str;
        }
    },
    isIE6: typeof document.body.style.maxHeight == "undefined"
});
Y.declare("widget.Base", null, {
    plugin: function(obj,opts){
		var config;
        if (typeof obj == "function") {
            try {
                var node = this.node;
                if (this.node instanceof jQuery) {
                    node = (this.node)[0]
                }
				if(opts){
					config=Y.mixin({},opts,{
					node:node
				 });
				}else{
					config={
						node:node
					}
				}
                new obj(config);
            } 
            catch (e) {
                Y.log(e, "貌似没有为其作为插件接口");
            }
        }else{
			Y.log(obj,"不存在这个构造函数!")
		}
    }
});

DEMO

可以拖动的div

我可以被拖动。。

拖放

我是可以放置的div
我是可以拖动的DIV

更多请checkout SVN:https://simple-ui.googlecode.com/svn/trunk

posted @ 2011-07-17 14:53  FED@Web  阅读(1027)  评论(0编辑  收藏  举报