Question

I have written the following block of code and it works in my scenario but I know it is dirty:

var navbarModule = (function($) {
    var self = {};
    var $login;

    self.hideLogin = function() {
        $login.hide();
    };

    self.showLogin = function() {
        $login.show();
    };

    $(document).ready(function() {
        $login = $(".navbar-form");
    });

    return self;
}(jQuery));

My goals for the code are:

  1. Only select the DOM element if necessary
  2. Cache the selected DOM element
  3. Guarantee that the cached DOM element exists

My code fails to achieve #1, achieves #2, and circumstantially achieves #3. I.e., for requirement #3, navbarModule.hideLogin() works if the DOM has fully loaded but does not if you call it before the navbar is present in the DOM.

Is there a way to achieve true lazy loading and caching that meets my goals without circumstantially working?

Was it helpful?

Solution

OK, now that you've explained what you mean by lazy caching, you can do this:

var navbarModule = (function($) {
    var self = {};
    var $login;

    function getLogin() {
        if (!$login || $login.length == 0) {
            $login = $(".navbar-form");
            return $login;
        }
    }

    self.hideLogin = function() {
        getLogin().hide();
    };

    self.showLogin = function() {
        getLogin().show();
    };

    return self;
}(jQuery));

Note:

If you call .showLogin() or .hideLogin() before there is a .navbar-form", then nothing will happen. It will create an empty jQuery object and the .hide() and .show() methods will simply not do anything. If you call it again later, it will see that the jQuery object is empty and look for ".navbar-form" again.

It is unclear why you think caching the login object is even required here. Give it an id value and just find it upon demand with document.getElementById() and it will be plenty fast.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top