If you've worked with vanilla DOM manipulation, you've probably found yourself in a situation when you have to save data associated with an element. Let's see how we can do this.
For the first time, you probably came up with the idea to save the data on the element object itself, like this
const setElementData = (el, data) => {
el.$dataKey = data;
}
const getElementData = (el) => {
return el.$dataKey;
}
// Usage
setElementData(document.querySelector('#some-el'), {
prop1: 'val',
prop2: someComplexValue
});
// Somewhere
const elData = getElementData(document.querySelector('#some-el'));
Even if this method works, it's not good. Adding custom props to an element object is not recommended and it can cause memory leaks if not done correctly.
So, what's the correct way to do it?
The correct way is to use a WeakMap
to store data for an element. The code will look like this
const elementDataMap = new WeakMap();
const setElementData = (el, data) => {
elementDataMap.set(el, data);
}
const getElementData = (el) => {
return elementDataMap.get(el);
}
// Usage
setElementData(document.querySelector('#some-el'), {
prop1: 'val',
prop2: someComplexValue
});
// Somewhere
const elData = getElementData(document.querySelector('#some-el'));
This way we are able to save data for an element without causing memory leaks. If you don't know what WeakMap
is, check out the MDN docs.
See ya!
Top comments (3)
In Python there is weakref too by the way but of course won't help with the DOM
docs.python.org/3/library/weakref....
Thanks for sharing. I hadn't heard of WeakMap.
I think your two get and set functions, in both cases, add unnecessary complexity and the built methods can make it clearer.
This below is much easier to follow for me and avoids relying on functions to have side effects on a global object.
I can see how putting use of
.$dataKey
in a function can help in larger application but in the first case you could just set and get directly without the functions.Also I think it should be mentioned that you can't use this .get on any element to find its data unless you first make a map and send data on the map.
That's good too. The main thing is the
WeakMap
after all, you can use it in any way you like to 😀