开发者

Storing an HTML node as key in an *object*

Similar to this SO question, I would like to use HTML nodes as keys in an object (not an array).

Example:

var _hotspots = {
                 [object HTMLDivElement] : { someProps:[1,2,3] },
                 [object HTMLDivElement] : { someProps:[1,2,3] }
                }

and so I might achieve things like this:

for( var a in _hotspots ){
    if(YAHOO.lang.hasOwnProperty(_hotspots, a)){
    alert('key nodeName: '+a.nodeName);
    }
}

So far, when I alert out 'a' above, it alerts out that it is in fact a开发者_如何学JAVA [object HTMLDivElement], so it all seemed fine - but I can't access properties on 'a', like nodeName.

Is what I am doing possible? Is it wrong? If I should be able to access properties on the object's key reference then please let me know and I'll write up a sample page.

cheers.


The keys of JavaScript objects are always character. You could store the id as the key and then retreive the element in your function.


It's now possible to do this with Map or Set objects, but a Map is more appropriate if you want to store key value pair, such as a regular object.

You could still add node as key with regular objects, but the problem is that the node is converted to a string, because objects can only store keys as strings, this means that the object can't distinguish unique nodes that have identical attributes/structure.

The reason Map works is because its keys can be any value, including functions, objects, or any primitive.

const divEl1 = document.querySelectorAll("div")[0];
const divEl2 = document.querySelectorAll("div")[1];

const obj = {};
const map = new Map();

obj[divEl1] = divEl1.getBoundingClientRect();
map.set(divEl1, divEl1.getBoundingClientRect());

console.log("Object: is divEl1? ", !!obj[divEl2]);
console.log("Map: is divEl1? ", map.has(divEl2));
console.log("Map: get divEl1 bounding properties", map.get(divEl1));
<body>
  <div class="foo" data-some-id="1">I am a <span>div</span></div>
  <div class="foo" data-some-id="1">I am a <span>div</span></div>
</body>

You can also use WeakMap and WeakSet to add node as keys. Using Map/Set, to store elements poses a potential memory issue once elements are removed from DOM, because they are still held in Map/Set and are not garbage collected. When using WeakMap/WeakSet, if no other references to those elements stored in those objects exist, those elements will be garbage collected.


You could use my own jshashtable, which accepts any object as key, but if it's not a problem for you to give all your elements an id then I'd recommend using an object with element IDs as keys, since that will be the simplest and most performant solution.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜