我想做的是能够动态地构建一个具有附加属性的自包含HTML块。
我不确定该怎么称呼,因为“小部件”现在意味着要在您的博客上贴上天赋或徽章。我说的是一个可重用,可定制,“复合”的JS / HTML(/ CSS)对象。
例如,一个简单的日期选择器。
document.body.appendChild(new DatePicker());
会产生
<div class="datepicker" name="...">
<select class="datepicker_monthSelect">
<option value="0">January</option>
....
</select>
<select class="datepicker_daySelect">
<option value="1">1</option>
....
</select>
<select class="datepicker_yearSelect">
<option value="2010">2010</option>
....
</select>
</div>
并具有像
var d = new DatePicker();
d.value = "2010-06-21";
d.name = "the_datepicker";
d.month = 5;
d.month = "June";
d.day = 21;
d.year = 2010;
如何(轻松)实现?这种情况下的最佳做法是什么?
最佳答案
我喜欢执行此操作的MooTools方法。任何JavaScript对象都可以定义toElement
方法,并且您可以使用MooTools的包装器将此对象附加到DOM。包装器将查询对象的toElement
属性,如果存在,则将调用toElement()
的返回值附加到DOM。为此,您必须使用包装器将其附加到DOM,而不是直接使用appendChild
。
function DatePicker(date) {
this.date = date;
}
DatePicker.prototype.toElement = function() {
// return a DOM representation of this object
};
var picker = new DatePicker();
以下是一些使用此方法的方法:
// retrieve the DOM node directly
document.body.appendChild(picker.toElement());
// use a wrapper to append, that queries toElement first
// DOM is a function like jQuery, that wraps the given DOM
// object with additional methods like append for querying toElement.
DOM(document.body).append(picker);
当然,您始终可以覆盖本机的
appendChild
方法,但是,我会而不是建议这样做。为了完整起见,这就是您要做的。使用闭包保留原始的
appendChild
方法,然后将其替换为新的方法,该方法首先检查是否已定义toElement
,然后检索该对象的元素表示形式(如果存在)。否则,请按原样添加传入的对象。(function(original) {
Element.prototype.appendChild = function(child) {
if('toElement' in child) {
original.call(this, child.toElement());
}
else {
original.call(this, child);
}
}
})(Element.prototype.appendChild);
如示例所示,将对象添加到DOM:
document.body.appendChild(new DatePicker());