日期:2014-05-17  浏览次数:20608 次

关于动态html/dom创建的过程

用过jquery的都知道下面这种用法:

?

    make: function(tagName, attributes, content) {
      var el = document.createElement(tagName);
      if (attributes) $(el).attr(attributes);
      if (content) $(el).html(content);
      return el;
    },

?这段代码是backbones.js View对象的方法,就是为了方便创建一个document element,以对象实行返回。

?

我在编程实践中弄了一个自己觉得蛮好用的一个类,对于创建dom对象很方便,尤其是有属性继承情况的。

先贴代码:

/**

* Begin	class defination XHtml : Html Dom生成辅助类
*/
var	XHtml =	Base.extend({
	constructor	: null,	
	dump : '' // 避免,结尾,在IE浏览器中语义错误
	},{

	createFn : function(tag, attr){
		return (function(tagIn, attrIn){
			return function(text, attr){
				attr = attr || {};
				if(attrIn)
					$.extend(attr, attrIn);
				var attrStr = '';
				for(key in attr)
					attrStr += key + '="' + attr[key] + '" ';

				return '<{0} {1}>{2}</{0}>'.format(tagIn, attrStr, text || '');
			}
		})(tag, attr);
	}, 

	input : function(val, attr){
		val	= val || '';
		var	attrStr	= '';
		if(attr){
			for(key	in attr)
				attrStr	+= key + '="' +	attr[key] +	'" ';
		}
		return '<input value="{0}" {1} />'.format(val, attrStr);
	}, 

	sel : function(ll, val, attr, canBlank){
		var	attrStr	= '';
		if(attr){
			for(key	in attr)
				attrStr	+= key + '="' +	attr[key] +	'" ';
		}
		var rr = '<select {0}>'.format(attrStr);

		var tpl = '<option value="{0}" {2} title="{1}">{1}</option>';

		var	defaultLabel = '-请选择-';
		if(canBlank){
			rr += tpl.format('', defaultLabel, '');
		}

		val = val || '';
		var optionStr = $(ll).map(function(){
			return tpl.format(this['code'], this['name'], val == this['code'] ? 'selected' : '');
		}).get().join('');
		return (rr + '{0}</select>').format(optionStr);
	}, 
	
	dump : '' // 避免,结尾,在IE浏览器中语义错误
});

$.extend(XHtml, {
	createInput : function(attr){
		return function(val, attrIn){
			attrIn = attrIn || {};
			if(attr)
				$.extend(attrIn, attr);
			return XHtml.input(val, attrIn);
		};
	}, 

	td : XHtml.createFn('td'),
	tr : XHtml.createFn('tr'),
	alink : function(txt, url, attr){
		var alinkIn = XHtml.createFn('a');
		attr = attr || {};
		attr.href = url;
		return alinkIn(txt, attr);
	},

	trJoin : function(attr){
		var arg = [];
		for (var i = 0; i < arguments.length; i++){
			if(typeof arguments[i] == 'string')
				arg.push(arguments[i]);
		}

		
		return XHtml.tr(arg.join(''), typeof attr == 'string' ? null : attr);
	}
});

$.extend(XHtml, {
	radio: function(name, ll, pender, keyName, keyVal, isFirstChecked, multiple){
		pender = pender || '&nbsp;';
		keyName = keyName || 'name';
		keyVal = keyVal || 'val';

		var fnRadio = XHtml.createInput({type: multiple ? 'checkbox' : 'radio', name: name});
		return _.map(ll, function(item, i){
			if(isFirstChecked && i == 0)
				return fnRadio(item[keyVal], {checked: 'true'}) + pender + item[keyName];
			else
				return fnRadio(item[keyVal]) + pender + item[keyName];
		}).join(pender);
	}
});

?

思路只是简单的拼接字符串,并不是dom对象的创建和操作。

根据具体需求,可以在此基础上再封装一层,业务相关的所为所为控件的视图部分。

还比较好用。

?

比如创建一个table就可以以下面方式:

?

?

with(XHtml){
	var fnTable = createFn('table', {class: 'table1'});
	var tpl = fnTable(
		trJoin(
			td(input('A')), 
			td(radio('testRadio', [{name: '男', val: 'M'}])), 
			td(sel([{name: '男', val: 'M'}], null, {name: 'testSelect'})), 
			td(''))
		);

	$('#wrap').html(tpl);
}

?

很有Groovy HtmlBuilder的feel啊,有些模板引擎(ruby)之类的就是这样风格,其实javascript一样可以做到的