日期:2014-05-16  浏览次数:20359 次

javascript控件开发之渲染对象
    前面我们写了文件加载,类继承,都比较基础,有了前面的框架, 后边我们还需要一个可见控件的渲染对象,也是我们本章讲的重点,
主要目的是跟据我们在dom元素上的配置,渲染出我们想要的效果,例如我们在div上配置一个code="com.ui.Botton"属性,就跟据指定的com.ui.Botton.js类来绘制我们的按钮,
实现思路是先读取所有的dom元素,查看是否有指定code的元素在,并执dom对应的控件代码。
我们在common下面增加文件render.js
/**
 * ui控件渲染
 * 参数:dom 占位符
 *       callBack 回调函数
 */
function render(dom, callBack){
	if(typeof dom == "undefined") return;
	//读取传入的dom参数的所有子元素
	var len = dom.childNodes.length;
	for(var i = 0; i < len; i++) {
	    //循环对各个dom子元素处理
		var curDom = dom.childNodes[i];
		//获取子元素的子元素数组
		var childDom = curDom.childNodes;
		//获取当前元素的id或name用于作控件的变量名,
		var comName = curDom.id || curDom.name;
		//如果重复就不渲染
		if(comName !== "" && typeof comName != "undefined" && comName != null) {
			if(typeof thisWindow.com[comName] === "undefined") {
			    //读取元素的code属性
				var code = curDom.attributes.code;
				if(typeof code != "undefined") {
					var code = code.nodeValue;
					//把code属性转换成类对象
					var comClass = eval(code);
					if(typeof comClass != "undefined") {
					    //如果有对应的类对象,则再读取option属性
						var option = curDom.attributes.option;
						if(typeof option != "undefined") {
							option = eval("(" + option.nodeValue + ")");
						}
						try {
						    //跟据code对应的ui控件对象,
							var ui = new comClass(option, curDom, true);
							//加入到com列表中,
							thisWindow.com[curDom.id || curDom.name] = ui;
							//返回当前容器,用于继续渲染子元素控件
							curDom = ui.getRectDom();
						} catch(e) {
						    //控件渲染错误时日志输出。
							thisWindow.LogInfo("create class " + code 
							+ " error:" + e.message);
						}
					} else {
					    //控件不存在时输出日志
						thisWindow.LogInfo("class " + code + " can not found.");
					}
				}
			} else {
			    //如果id重复,提示,输出日志
				thisWindow.LogInfo(comName + " is exist");
			}
		}
		if(childDom.length > 0 && curDom != null && typeof curDom != "undefined") {
		    //如果还有子元素,则继续渲染
			render(curDom);
		}
	}
	if(typeof callBack == "function") {
		callBack();
	}
};
//第一次默认渲染body对象下的控件
render(document.body, function(){
	if(typeof thisWindow.onAfterRender == "function") {
	    //渲染后事件
		thisWindow.onAfterRender();
	}
});

我们把这个文件也加入到staticScript.js的文件列表中,
staticScript = [
    "../css/com.comStyle.css",
    "extend.js",
    "render.js"
]

首先,为了后续定义的控件命名不至于混乱, 我们先定义一个命名空间函数nameSpace(nameSpace.js),
function nameSpace(){
    var arg = arguments, obj = null, i, j, arr, ns;
		// 保存当前的nameSpace
		for (i = 0; i < arg.length; i++){
			// 以"."分割字符串
			arr = arg[i].split(".");
			// 取出第一节点对象
			ns = arr[0];
			// 判断是否存在ns字符串对应的对象,若不存在则进行初始化成原始对象{}
			if(window[ns] === undefined){
				window[ns] = {};
			}
			obj = window[ns];
			// 循环判读对象已存在,如果未存在,则初始化成原始对象{}
			for (j = 1; j < arr.length; j++){
				if(obj[arr[j]] === undefined){
					obj[arr[j]] = {};
				}
				obj = obj[arr[j]];
			}
		}
		return obj;
}

把该文件放入common文件夹中,并添加到staticScript.js列表中,如下
staticScript = [
    "../css/com.comStyle.css",
    "extend.js",
    "nameSpace.js",
    "render.js"
]

到此,我们的控件框架已经形成,如下
+--demo
     +--script
          +--common
               +--init.js
               +--staticScript.js
               +--extend.js
               +--render.js
               +--nameSpace.js
          +--css
    &n