简体   繁体   中英

Assigning a Javascript namespace to an HTML element and calling functions defined in namespace from element

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

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 (ie 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.)

ps 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

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM