0

I am trying to call remove class using this call:

MyUtils.removeClass(e,"empty");

But I am getting the error "Cannot read property "removeClass" of Undefined" in my debugger. I can't seem to figure out what it is that I am missing from my removeClass call.

This is my removeClass function.

var removeClass = function removeClass(el, classStr) {
    delete el.className;
};

Here is the complete code, the HTML is testing the two methods.

<body>
    <div id="foo" class="column empty">Halloween!</div>
    <script type="text/javascript" src="utils.js"></script>
    <script>
        var e = document.getElementById("foo");
        var q = function (s){ document.write("<div>"+s+"</div>"); }
        q("initial (" + e.className+")");
        MyUtils.removeClass(e,"empty");
        q("removed empty (" + e.className+")");
        MyUtils.addClass(e,"column");
        q("added column again (" + e.className+")");
        MyUtils.removeClass(e,"scary");
        q("removed scary (" + e.className+")");
        MyUtils.addClass(e,"lum");
        q("added lum (" + e.className+")");
        MyUtils.removeClass(e,"column");
        q("removed column (" + e.className+")");
        MyUtils.addClass(e,"foo");
        q("added foo (" + e.className+")");
        MyUtils.addClass(e,"bar");
        q("added bar (" + e.className+")");
    </script>
</body>

And the MyUtils function:

var MyUtils = (function() {

function addClass(el, classStr) {
    if(el.className !== classStr) {
        el.className = classStr;
    }
};

var removeClass = function (el, classStr) {
    delete el.className;
};

var walkTheDom = function walkTheDom(el, f) {
    f(el);
    el = el.firstChild;
    while(el) {
        walkTheDom(el,f);
        el = el.nextSibling;
    }
};

var getElemebtsByClassName = function getElementsByClassName(c) {
    var results = [];
    var re = new RegExp("\\b"+c+"\\b");
    var f = function (el) {
        if(el.nodeType === 1) {
            if(el.className.search(re) !== -1) {
                results.push(el);
            }
        }
    };
    walkTheDom(document.body, f);
};

}());
TheCrownedPixel
  • 359
  • 6
  • 18

2 Answers2

2

The problem is that your functions can only be accessed inside MyUtils, but not from the outside.

You could use

var MyUtils = {
  addClass: function(el, classStr) {
    if (el.className !== classStr) {
      el.className = classStr;
    }
  },
  removeClass: function(el, classStr) {
    delete el.className;
  }
  /*, ... */
};

Or, if you also want to have private variables,

var MyUtils = (function(){
  var thisIsPrivate = whatever;
  function addClass(el, classStr) {
    if (el.className !== classStr) {
      el.className = classStr;
    }
  },
  function removeClass(el, classStr) {
    delete el.className;
  }
  /* ... */
  // Export public properties to the outside:
  return {addClass: addClass, removeClass: removeClass/*, ... */};
})();
Oriol
  • 274,082
  • 63
  • 437
  • 513
1

With a revealing module, you'll have to specify what from it is revealed as MyUtil:

var MyUtil = (function () {
    // ... (define the functions of the module)

    // reveal its "public" functions
    return {
        addClass: addClass,
        removeClass: removeClass,
        walkTheDom: walkTheDom,
        getElemebtsByClassName: getElemebtsByClassName
    };
})();

Without this last step, MyUtil will hold the undefined value without any references to the functions being defined.

Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199