3

How can one assign a Javascript namespace to an HTML element and call functions defined in said namespace on this element?

I asked this other question: Attaching JavaScript to the prototype of an ASCX client side instance

The previous question answered the how to do it, but now I am curious how this works on a pure Javascript/HTML level. And I'm no closer to figuring it out.

Let assume I have an HTML page with just a textbox:

<html>
   <body>
    <div>
     <input type="text" id="MyTextBox" />
    </div>
   </body>
</html>

In a browser, I can do document.getElementById('MyTextBox').

My question is however, using just javascript, how can I assign the object returned a javascript type so that from the object I can call functions defined in the namespace?

For instance, I want to do:

var x = document.getElementById('MyTextBox');
x.SetTheText('blah');

and in my custom namespace/type/class I would have defined SetTheText as

function SetTheText(text) {
    this.value = text;
}

How do I say MyTextBox is an object that can run functions defined in a JS namespace. I hope this makes sense

2
  • 1
    I like Flambino's answer. I also wanted to share a useful link: crockford.com/javascript/inheritance.html#sugar There are some handy little examples of systematic ways of doing the same thing. Commented Aug 10, 2011 at 1:58
  • +1 for linking to Crockford. He still does a little bit of native object extending (which, as mentioned, can be risky), but I'm not going to argue with the great JS greybeard :) Commented Aug 10, 2011 at 2:03

2 Answers 2

3

Basically, you can add any kind of property to (almost) any kind of JS object. And if you add a function to an object, that function's this will be the object.

In other words

var x = document.getElementById('MyTextBox'); // a DOM object
x.setTheText = function(text) {
     this.value = text;
};
x.setTheText('blah'); // bingo

If you want to extend an entire class of objects, you can do that too, via the prototype

HTMLTextAreaElement.prototype.setTheText = function(text) {
    this.value = text;
};
someRandomTextArea.setTheText("blah"); // bingo. Again.

However, this is not really recommended, as you're messing with objects that are outside your control (i.e. it's fragile as other scripts and browser updates and whatnot might get in the way). Also, you might break some other piece of code by doing this.

A better solution (in many ways) is the jQuery solution of wrapping an unmodified DOM element in another object, and calling methods on the wrapper object rather than the element directly (Personally, I rather like the "pretty" code that can come from just extending native JS objects, but alas, it's not safe, so I'm trying to quit that.)

p.s. Classes are Captilized in javascript; methods are camelCase. I've edited the code accordingly. It's not something that's enforced by anything, but style's style.


Edit: For comparison, you can look at the prototype.js library, which works its magic by extending the DOM. Again, in my opinion, it makes for some very pretty code compared to jQuery's constant invocations of $(...).xyz(...), but it's still a slightly dangerous route to take

Sign up to request clarification or add additional context in comments.

2 Comments

There are no classes in javascript. Prototype.js v2.0 will no longer modify host objects.
@RobG: I know there are no "classes" in the classical sense, only constructors. But frankly, calling it a "class" gets the point across faster, if you don't want to digress into an explanation of prototypal inheritance (and classical classes or not, you can still say "class of objects" as in "all of a kind"). I know Prototype 2 will use wrappers, and I'm looking forward to see how they'll implement it. But until v2 is out, "prototype.js" is v1.7, which extends the DOM. All of what I wrote was simplified on purpose
2

You should not modify host objecs, all of the major libraries agree on that. Use a wrapper object instead:

<input type="text" id="inp0">

<script type="text/javascript">

function CreateCustomElement(el) {
  this.element = el;
}

CreateCustomElement.prototype = {
  setTheValue: function(text) {
    this.element.value = text;
  }
}

var x = new CreateCustomElement(document.getElementById('inp0'));
x.setTheValue('foo');

</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.