tags:

views:

55

answers:

3

Is it possible to augment a DOM element by adding a new property to it as augmenting a normal JavaScript object? For example, can we add a new property of a button or an input, say a value that indicates when was the last time user click on it?

+1  A: 

Yes. You can sometimes find it described as bad form. The obvious drawback is that in later versions of Web standards, the DOM element may have new properties added to it which will clash with your custom property, so if you do use this technique, choose a name that is unlikely to clash, e.g. incorporate your company name into it.

Another potential problem is that DOM objects in some browsers are not properly garbage collected. Instead they are reference counted. This means that if you create a system of circular references through custom properties, you may cause a memory leak.

For example, this may cause a memory leak, because there is a circular reference between the DOM and javascript objects:

var myJsObj = {};
var myDomElt = document.getElementById('myId');
myJsObj.domElt = myDomElt;
myDomElt.jsObj = myJsObj;

It is, however, safe to add a property that just holds a primitive value:

myDomElt.fullTitle = "My DOM Element";

Although the warning that the DOM standard may change is still important; what if HTML7 defines a fullTitle property on DOM elements? Your site will have unpredictable behaviour.

An alternative is to use the $.data feature of jQuery:

$(myDomElt).data('fullTitle', 'My Dom Element');
var retrieved = $(myDomElt).data('fullTitle');
Daniel Earwicker
@Daniel, Amit, Forgot to ask, how to do it, if it's possible.
Paul
@Paul, is that still unclear? Like all JS objects, DOM objects are "expando", meaning that you can assign to any property name and it automatically creates a new property on the object. So `x.foo = 5` will create property `foo` on object `x` if it doesn't already exist. You can use `delete x.foo` to delete property `foo` from object `x`.
Daniel Earwicker
@Daniel, yes! I added my question before you put more answers! Thanks!
Paul
+1  A: 

Yes we can do it in some case.But can u please elaborate your question.What exactly you want to do with input button.

Please check the following link.

http://www.quirksmode.org/dom/inputfile.html
Amit
+1  A: 

It's possible but is a really bad idea. Daniel Earwicker's answer mentions some reasons why it's a bad idea. I'd add these:

  • DOM nodes are host objects and host objects can do what they like. Specifically, there is no requirement in the ECMAScript spec for host objects to allow this kind of extension, so browsers are not obliged to allow it. In particular, new browsers may choose not to, and existing code relying on it will break.
  • Not all host objects in existing browsers allow it. For example, text nodes and all ActiveX objects (such as XMLHttpRequest in older IE and XMLDOM objects, used for parsing XML) in IE do not, and failure behaviour varies from throwing errors to silent failure.
  • In IE, the ability to add properties can be switched off for a whole document, including all nodes within the document, with the line document.expando = false;. Thus if any of the code in your page includes this line, all code relying on adding properties to DOM nodes will fail.
Tim Down
@Tim, so is there any way to add a flag (i.e., a true/false property ) to an object?
Paul
In general, it is possible to add properties to DOM nodes, including boolean flags, it's just not advisable. If you want to associate objects with DOM nodes and you were certain each node had an ID, you could associate node IDs with objects using an object whose property names were node IDs. Otherwise you could use something like my jshashtable (http://code.google.com/p/jshashtable) to associate values with DOM nodes (or any other object, including host objects).
Tim Down
@Tim, Your project sounds very exciting! Actually I've been looking for some data structure that uses objects as keys. If my understanding is correct, that's what your project does. I can store a DOM tree in the hashtable, whose keys are DOM objects and values are the flags. Would it be the way you recommend to work in my case?Btw, what's host objects?
Paul
A host object is an object describing some aspect of the environment, provided by the environment. See http://www.jibbering.com/faq/#hostObject for a little more detail. In the case of browsers, this means things like DOM nodes and `XMLHttpRequest`. You can use jshashtable as you described; the thing to be aware of is performance. You may find that with a lot of DOM node keys, performance becomes slow unless you provide a hashing function. The jshashtable documentation has a full discussion of this issue.
Tim Down
If a DOM object is dynamically changed, say a property is added or the innerHTML is changed, is there a new object created in the hashtable?
Paul
No. You just need to be careful not to use a hashing function that is affected by changes like that. If you're creating a hash table where you know in advance that all the keys will be DOM nodes, you could use something like `function(node) { return node.nodeType + "_" + node.nodeName; }`. With no hashing function, when you call `get()` the hash table will simply look through a list of all its keys until it finds the required one.
Tim Down