Can I add arbitrary properties to JavaScript DOM objects, such as <INPUT>
or <SELECT>
elements? Or, if I cannot do that, is there a way to associate my own objects with page elements via a reference property?

- 115,249
- 25
- 154
- 140

- 40,327
- 71
- 187
- 281
7 Answers
ECMAScript 6 has WeakMap which lets you associate your private data with a DOM element (or any other object) for as long as that object exists.
const wm = new WeakMap();
el = document.getElementById("myelement");
wm.set(el, "my value");
console.log(wm.get(el)); // "my value"
Unlike other answers, this method guarantees there will never be a clash with the name of any property or data.

- 5,635
- 2
- 33
- 44
-
1But doesn't that mean that you have to maintain the `wm` reference throughout? Seems a little limiting. – Julian Knight Apr 16 '22 at 16:26
-
You don't want to maintain that wm reference? No need to expose it, if you rather use a utility function like setArbitraryValueTo(el,value) or getArbitraryValueFrom(el). – Salketer Jul 01 '22 at 07:59
Yes, you can add your own properties to DOM objects, but remember to take care to avoid naming collisions and circular references.
document.getElementById("myElement").myProperty = "my value";
HTML5 introduced a valid way of attaching data to elements via the markup - using the data-
attribute prefix. You can use this method in HTML 4 documents with no issues too, but they will not validate:
<div id="myElement" data-myproperty="my value"></div>
Which you can access via JavaScript using getAttribute()
:
document.getElementById("myElement").getAttribute("data-myproperty");

- 338,112
- 86
- 474
- 445
-
1
-
1
-
18data- attributes can only store strings (or objects serializable/deserializable to/from strings), not general runtime objects, whereas setting a new property on a dom object can. – Triynko Mar 16 '17 at 17:40
-
1What's exactly the issue with circular references? An object A having a reference to an object B which has a reference to A is not an issue in general, so what is the situation that must be avoided in the case of arbitrary properties attached to a DOM element? – matteo Apr 18 '17 at 17:56
-
@matteo A circular reference *could* lead to a memory leak. https://stackoverflow.com/questions/7347203/circular-references-in-javascript-garbage-collector – Yay295 Aug 23 '18 at 22:32
-
2@matteo - Back in 2010, when Andy wrote this answer, there was an issue in Internet Explorer related to DOM elements having references to JavaScript objects on arbitrary properties. But that was fixed in a later version of IE, so the circular references thing is no longer an issue. – T.J. Crowder Jan 31 '22 at 11:31
Sure, people have been doing it for ages. It's not recommended as it's messy and you may mess with existing properties.
If you are looping code with for..in
your code may break because you will now be enumerating through these newly attached properties.
I suggest using something like jQuery's .data
which keeps metadata attached to objects. If you don't want to use a library, re-implement jQuery.data

- 183,342
- 71
- 393
- 434
-
Cool... Is `data` used by jQuery itself or am I free to assign any value to it? – Tony the Pony Nov 23 '10 at 16:45
-
1`$.data` is defined by jQuery. You would use it like `$('#el').data('key', 'value')`. – meder omuraliev Nov 23 '10 at 16:46
-
1It's `$(element).data('name', value)` to set a value, and `$(element).data('name')` to read it. – gen_Eric Nov 23 '10 at 16:47
-
1I assume you know how to do it the manual DOM way, `el['data-foo'] = 'value';` – meder omuraliev Nov 23 '10 at 16:47
-
1There are bugs/inconsistencies with `getAttribute` and `setAttribute` in IE, if you dont decide to use `$.data` prefix your attribute with `data-` – meder omuraliev Nov 23 '10 at 16:47
-
2How would `for...in` loops break just by having an extra property? – Hugh Guiney Jan 17 '19 at 22:52
Do you want to add properties to the object, or attributes to the element?
You can add attributes using setAttribute
var el = document.getElementById('myelement');
el.setAttribute('custom', 'value');
or you can just add properties to the javascript object:
var el = document.getElementById('myelement');
el.myProperty = 'myValue';

- 4,653
- 3
- 29
- 40
-
if anyone forgot the difference between property and attribute -> quick link https://stackoverflow.com/a/6004028 – wlf Jul 16 '21 at 00:18
In case someone is wondering in 2015, yes, you can - and jQuery is doing just that in data. Just pick future-proof names like vendor prefixes or time-based random suffixes (jQuery).

- 1,977
- 17
- 14
-
1But jQuery is using an internal cache were the data is saved, the data is not saved in the DOM Element itself. See also: https://stackoverflow.com/questions/7200722/jquery-expando-properties – RiZKiT Jun 04 '19 at 07:53
-
1You linked to the master branch of jQuery. Since master branches change, please consider linking to a particular version. – Michael Franzl Apr 11 '20 at 08:02
If you must, don't use standard HTML attributes. Here's a tutorial on using custom attributes:
http://www.javascriptkit.com/dhtmltutors/customattributes.shtml
It's HTML5, but it's backward-compatible.

- 17,371
- 5
- 40
- 51
I was exploring answers, none have mentioned that in modern JavaScript we can set attributes on domElements
using dataset
property, it could use on HTMLOrForeignElement
(that's a mixin of several features common to the HTMLElement
, SVGElement
and MathMLElement
interfaces).
According to MDN
The
dataset
property on the HTMLOrForeignElement interface provides read/write access to all the custom data attributes(data-*)
set on the element. This access is available both in HTML and within the DOM. It is a map ofDOMStrings
, one entry for each custom data attribute.
let element = document.getElementById("test");
let footer = document.querySelector("#output");
/* get element values using camelCase names through .dataset */
let sample = element.dataset.sample;
let sampleNumber = element.dataset.sampleNumber;
let dataFromElement = sample + " :: " + sampleNumber;
footer.innerHTML = element.innerHTML + dataFromElement;
<input type="hidden" id="test" data-sample="Sample" data-sample-number=34 />
<div id="output"> </div>
Although there are concerns about Internet Explorer support and performance on this you can check here.

- 185
- 11
-
1The issue with this is that the dataset properties are just attributes and so passing in an object results in it being flattened to `[object Object]`. – Julian Knight Apr 16 '22 at 16:20