在 Javascript 中使用模块化设计模式,选择 DOM
Using modular design pattern in Javascript with DOM selections
我已经关注 Modular Design Pattern 一段时间了,发现它非常有用,因为它有助于很好地维护代码以及将块分离成模块。
经常使用 jQuery
模块结构导致我的大部分 applications/code 遵循以下结构:
(function() {
var chat = {
websocket: new WebSocket("ws://echo.websocket.org/"),
that: this,
init: function() {
this.scrollToBottom();
this.bindEvents();
this.webSocketHandlers();
},
bindEvents: function() {
this.toggleChat();
this.filterPeople();
this.compose();
},
elements: {
indicator: $(".indicator"),
statusText: $(".status-text"),
chatHeadNames: $(".people li .name"),
filterInput: $("#filter-input"),
msgInput: $("#msg-input"),
sendBtn: $(".send")
},
...
...
...
filterPeople: function() {
var that = this;
this.elements.chatHeadNames.each(function() {
$(this).attr('data-search-term', $(this).text().toLowerCase());
});
},
...
...
};
chat.init();
})();
我想知道的是,通过 jQuery
引用我的所有元素作为单个变量 chat.elements
的一部分是否是 好的做法?
我的一部分告诉我,它确实是一次引用所有选择器并将它们缓存在变量中的好方法,这样就可以使用缓存的变量多次使用同一元素(而不是多次 DOM 个选择)。
我的另一部分告诉我,这可能是一个反模式,需要时应选择特定元素并在本地缓存。
我自始至终都使用了类似的结构,并且对代码的反应不一,但没有什么可靠的。任何帮助,将不胜感激。谢谢!
缓存选择器是一件好事。坚持下去是个好主意。与重复查询 DOM 相同的东西相比,它提高了性能。您上面的代码看起来与 BackboneJS 和 MarionetteJS 代码非常相似。
不过我确实有一些警告要告诉你:
- 此模式可能会导致内存泄漏。考虑这样一种情况,你销毁了一个子视图,但你保留了对选择它的东西的引用。这称为悬挂指针。景色不会真的消失。所有绑定将保留。活动将在幕后继续火爆。
- 您最终会 运行 遇到一个错误,您决定重新渲染部分屏幕。然后需要清理所有绑定,您需要记住删除和选择器。如果你不这样做,你几乎肯定会 运行 陷入这样的问题:你想知道为什么一个事件确实在触发,但屏幕上似乎什么也没有发生……(这是因为它发生在屏幕外,对您尝试删除的元素仍然存在...有点)。
- 您当前查询元素的方式导致搜索整个页面。看看https://api.jquery.com/find/。如果您缓存一个选择器,然后在该选择器内执行搜索,它可能会给您带来一点性能提升。
- 我认为,如果聊天模块只为其子项提供选择器,那么这是一个很好的模式。喜欢:
<div id="chat-module">
<div class="indicator">...</div>
<div class="status-text">...<div>
...
</div>
<script src="and your chat module.js"></script>
// your chat module selecting .indicator:
// $('#chat-module.indicator')
- 此外,为您的模块添加关机功能。因此,当您将其从视图中删除时(如在单页应用程序中),您可以使选择器无效并分离事件处理程序,例如:
delete this.elements.indicator
和事件分离代码。
也有 other/better 模式,例如,当用户键入内容时,您会触发一个事件,并在您的模块中捕获该事件。将UI和代码分开。
我已经关注 Modular Design Pattern 一段时间了,发现它非常有用,因为它有助于很好地维护代码以及将块分离成模块。
经常使用 jQuery
模块结构导致我的大部分 applications/code 遵循以下结构:
(function() {
var chat = {
websocket: new WebSocket("ws://echo.websocket.org/"),
that: this,
init: function() {
this.scrollToBottom();
this.bindEvents();
this.webSocketHandlers();
},
bindEvents: function() {
this.toggleChat();
this.filterPeople();
this.compose();
},
elements: {
indicator: $(".indicator"),
statusText: $(".status-text"),
chatHeadNames: $(".people li .name"),
filterInput: $("#filter-input"),
msgInput: $("#msg-input"),
sendBtn: $(".send")
},
...
...
...
filterPeople: function() {
var that = this;
this.elements.chatHeadNames.each(function() {
$(this).attr('data-search-term', $(this).text().toLowerCase());
});
},
...
...
};
chat.init();
})();
我想知道的是,通过 jQuery
引用我的所有元素作为单个变量 chat.elements
的一部分是否是 好的做法?
我的一部分告诉我,它确实是一次引用所有选择器并将它们缓存在变量中的好方法,这样就可以使用缓存的变量多次使用同一元素(而不是多次 DOM 个选择)。
我的另一部分告诉我,这可能是一个反模式,需要时应选择特定元素并在本地缓存。
我自始至终都使用了类似的结构,并且对代码的反应不一,但没有什么可靠的。任何帮助,将不胜感激。谢谢!
缓存选择器是一件好事。坚持下去是个好主意。与重复查询 DOM 相同的东西相比,它提高了性能。您上面的代码看起来与 BackboneJS 和 MarionetteJS 代码非常相似。
不过我确实有一些警告要告诉你:
- 此模式可能会导致内存泄漏。考虑这样一种情况,你销毁了一个子视图,但你保留了对选择它的东西的引用。这称为悬挂指针。景色不会真的消失。所有绑定将保留。活动将在幕后继续火爆。
- 您最终会 运行 遇到一个错误,您决定重新渲染部分屏幕。然后需要清理所有绑定,您需要记住删除和选择器。如果你不这样做,你几乎肯定会 运行 陷入这样的问题:你想知道为什么一个事件确实在触发,但屏幕上似乎什么也没有发生……(这是因为它发生在屏幕外,对您尝试删除的元素仍然存在...有点)。
- 您当前查询元素的方式导致搜索整个页面。看看https://api.jquery.com/find/。如果您缓存一个选择器,然后在该选择器内执行搜索,它可能会给您带来一点性能提升。
- 我认为,如果聊天模块只为其子项提供选择器,那么这是一个很好的模式。喜欢:
<div id="chat-module">
<div class="indicator">...</div>
<div class="status-text">...<div>
...
</div>
<script src="and your chat module.js"></script>
// your chat module selecting .indicator:
// $('#chat-module.indicator')
- 此外,为您的模块添加关机功能。因此,当您将其从视图中删除时(如在单页应用程序中),您可以使选择器无效并分离事件处理程序,例如:
delete this.elements.indicator
和事件分离代码。
也有 other/better 模式,例如,当用户键入内容时,您会触发一个事件,并在您的模块中捕获该事件。将UI和代码分开。