包装JavaScript对象内的DOM元素
我注意到了我一直在写的JavaScript中的一种常见模式,并且想知道是否已经有一种模式定义类似最佳实践的模式? 从本质上讲,它是如何获得一个DOM元素并将其包装/关联到一个JavaScript对象。 以此示例为例,您需要在Web应用程序中使用过滤器。 你的页面如下所示:
<html>
<head></head>
<body>
<div id="filter"></div>
</body>
</html>
然后你会像这样包装元素:
var myFilter = new Filter({
elem: document.getElementById('filter'),
prop: 'stacks-test',
someCallback: function() {
// specify a callback
}
});
和JavaScript(其中spec是传递给构造函数的对象):
var Filter = function(spec) {
this.elem = spec.elem;
this.prop = spec.prop;
this.callback = spec.someCallback;
this.bindEvents();
};
Filter.prototype.bindEvents = function() {
var self = this;
$(this.elem).click(function(e) {
self.updateFeed();
};
};
Filter.prototype.updateFeed = function() {
this.prop; // 'stacks-test'
this.callback();
// ...
// code to interact with other JavaScript objects
// who in turn, update the document
};
这种方法称为什么,最佳实践和注意事项是什么?
您可能对Dojo的小部件库Dijit感兴趣 - 如果我能正确理解您的问题,它基本上可以解决您所问的问题以及更多问题。
在Dijit中,一个小部件本质上封装了一个DOM节点,其内容,任何定义其行为的JavaScript,以及(单独导入)CSS来设计其外观。
小部件有自己的生命周期,注册表和事件(包括许多简单地映射到小部件内的节点上的DOM事件,例如myWidget.onClick
可以有效地调用myWidget.domNode.onclick
)。
小部件可以(但不必)将其初始内容定义在单独的HTML模板文件中,通过该文件也可以将模板内的节点上的事件绑定到小部件方法,并且可以在小部件上设置属性节点在模板中。
我几乎没有在这里抓到表面。 如果您想了解更多信息,可以从这些参考页面开始:
所有人都说,我不知道你最终的目标是什么,也许这对你的目的来说很有意思(考虑到我把一个其他的图书馆扔给你),但是认为它可能会激起你的兴趣。
继续我对这个问题的评论,jQuery是这项工作的一个潜在工具,因为它已经为你所追求的内容提供了一些基础。 然而,尽管如此,它确实引入了自己的复杂性,并且并不是所有的“jQuery方法”都是平等的。 我会提出一种使用jQuery作为“对象模型”的方法,但它可能会或可能不适合您的需要。
首先要做的事情。 jQuery的哲学是,你首先选择元素,使用$()
或等价的jQuery()
来启动所有的事情。 所有的操作都是从这个开始的。 与创建一个包装元素并保持对该包装器的引用的对象相比,这是一种稍微不同的思维方式,但本质上这就是jQuery为您做的。 调用$('#some-id')
来获取id为“some-id”的元素并将其包装在一个jQuery对象中。
一种方式:编写“过滤器”插件。
用一个initFilter()
jQuery方法替换你的构造函数。 你可以通过修改jQuery原型并使用jQuery对象作为包装来实现。 jQuery的原型被jQuery.fn
引用,所以:
jQuery.fn.initFilter = function (prop, callback) {
// Save prop and callback
this.data('filter-prop', prop);
this.data('filter-callback', callback);
// Bind events (makes sense to do this during init)
this.click(function () {
$(this).updateFeed();
});
};
然后为updateFeed()
做类似的事情:
jQuery.fn.updateFeed = function () {
this.data('filter-prop');
this.data('filter-callback')();
});
并像这样使用它:
$('#filter').initFilter(prop, callback);
请注意, updateFeed
可以简单地插入到点击处理程序中,以防止对jQuery名称空间造成不必要的污染。 然而,像这样使用jQuery的一个优点是,如果以后需要调用某个函数,则不需要保留该对象的引用,因为jQuery将所有引用绑定到实际元素。 如果你想以编程方式调用updateFeed
,那么:
$('#filter').updateFeed();
然后将被调用到正确的对象上。
有些事情要考虑
这种方法肯定有缺点。 一个是所有的属性,我们使用.data()
保存在元素上,在所有的jQuery函数之间共享。 我试图通过在属性名称前添加“filter-”来减轻这一点,但取决于对象的复杂性,这可能不合适。
此外,这种确切的方法可能不适合需要大量操作的对象(即具有许多函数的对象),因为所有这些函数对于所有jQuery对象都是通用的。 有许多方法可以封装我不会在这里介绍的所有内容,但jQuery-ui使用它们的小部件来完成此操作,而且我正在尝试在我创建的库中另一个替代方案。
然而,拉回来一点,我首先建议使用jQuery的唯一原因是您的Filter对象看起来与DOM紧密相关。 它将事件绑定到DOM,它基于用户交互来修改DOM,基本上它看起来住在DOM中,所以使用一些基于DOM的,即jQuery。
链接地址: http://www.djcxy.com/p/4419.html上一篇: Wrapping a DOM element inside a JavaScript object
下一篇: jqGrid filter or search by date not working client side