创建复合Javascript / HTML“小部件”

时间:2010-06-22 01:29:29

标签: javascript html widget

我想要做的是能够动态创建一个具有其他属性的自包含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;

如何(轻松)完成?这种情况的最佳做法是什么?

3 个答案:

答案 0 :(得分:1)

这有几个不同的选择。

你可以'子类化'元素对象,但由于Javascript假装尽可能少的面向对象,这将是非常低效的。 (另外,扩展主机对象为yuck。)

但是,我采取的方法是在to_html'类'上定义DatePicker函数。

理论上,此方法将采用DatePicker的属性并使用它们来创建HTML。

并且,如果您将此HTML保存在DatePicker中,您将有一种简单的方法来更新它并在代码中进一步访问其值。

答案 1 :(得分:1)

我喜欢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());

答案 2 :(得分:0)