Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using modular design pattern in Javascript with DOM selections

I have been following the Modular Design Pattern for quite some time now and find it extremely useful as it helps in the well maintenance of code & separation of blocks into modules.

Regular usage of the module structure with jQuery has led to most of my applications/code following the below structure:

(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();
})();

What I would like to know is whether referencing all my elements via jQuery as part of a single variable chat.elements is a good practice?

One part of me tells that it indeed is a good way to reference all your selectors at once and cache them in variables so that multiple usages of the same element can be done with the cached variables (instead of multiple DOM selections).

Another part of me tells that this might be an anti-pattern and specific elements should be selected and cached locally when required.

I have used similar structures throughout and have got mixed responses about the code, but nothing solid. Any help would be appreciated. Thanks!

like image 895
nashcheez Avatar asked Feb 27 '17 12:02

nashcheez


People also ask

What is modular design pattern JavaScript?

The Module Pattern is one of the important patterns in JavaScript. It is a commonly used Design Pattern which is used to wrap a set of variables and functions together in a single scope. It is used to define objects and specify the variables and the functions that can be accessed from outside the scope of the function.

Which design pattern provides modularity and encapsulation in JavaScript?

The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.

What is the main advantage of using the module pattern in JavaScript?

The module pattern in JavaScript is one of the most used design patterns, used for keeping groups of code independent from each other. Modules allow us to break up different parts of our code to make it easier to maintain and understand. Thus enabling us to keep units of our code clean, separated, and organized.

What is modular design pattern?

In software engineering, the module pattern is a design pattern used to implement the concept of software modules, defined by modular programming, in a programming language with incomplete direct support for the concept.


2 Answers

Caching the selectors is a good thing. Hanging on to them is a good idea. It improves performance over repeatedly querying the DOM for the same thing. The code you have above looks very similar to BackboneJS and MarionetteJS code.

I do have some warnings for you though:

  1. This pattern could cause memory leaks. Consider the case where you destory a subview, but you keep a reference to something that selected it. This is called a dangling pointer. The view won't really disappear. All bindings will remain. Events will continue to fire behind the scenes.
  2. You will eventually run into a bug where you decided to re-render part of your screen. Cleaning up all your bindings is then required and you need to remember to delete and selectors. If you don't do this you will almost certainly run into issues where you wonder why an event is indeed firing but nothing appears to happen on screen.... (this will be because its happening off screen, to the element that you tried to delete, that still exists... sorta).
  3. The current way you are querying for elements causes searches against the entire page. Take a look at https://api.jquery.com/find/. If you cache one selector and then perform searches within that selector it may gain you a little performance bump.
like image 130
Parris Avatar answered Oct 18 '22 23:10

Parris


  • I think, If the chat module has selectors only for its children, then it's a good pattern. Like:
<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')
  • Also, add a shut-down function to your module. So, when you remove it from the view (as in a single-page-app), you can nullify your selectors and detaching event handlers, like: delete this.elements.indicator and event detaching code.

There are also other/better patterns for this, like, when a user types something, you fire an event, and catch that event in your module. To separate UI and the code.

like image 1
Inanc Gumus Avatar answered Oct 19 '22 00:10

Inanc Gumus