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