I tested adding arbitrary fields to HTML elements in JavaScript and it worked as expected:
const element = document.getElementById('element-id');
element.greet = (message) => { alert(message); };
element.friendElement = document.createElement('div');
element.greet(element.friendElement.innerText);
The alert shows up with the message, but I'm concerned:
- Do all the major browsers support this behavior?
- Is there a pattern for choosing new field name to make sure it won't conflict with names that the browsers use as fields for the elements?
- Is there any reason I should avoid adding arbitrary fields to HTML elements?
I wish HTML elements had another standard field like oncustomevent that can be set to a user defined function.
CodePudding user response:
It should work, but it's not a good idea, because a future change to the DOM specification might add those properties, and your code would conflict.
The DOM API already provides a place for application-defined string data, the dataset
property, which corresponds to data-XXX
attributes. So you can write:
element.dataset.message = 'Hello, world';
There's nothing equivalent for functions, though. Instead of making it a property, you could just use a regular function.
function greet(element) {
alert(element.dataset.message);
}
CodePudding user response:
DOM elements are not "namespaces" for related stuff, they are entities with a specific purpose, which is reflected as a particular set of data and behavior. Although there are some objects in JavaScript that serve the purpose of namespacing related functionality (Math
, Intl
, etc.), they usually are unique and "famous" enough to be a good exception to the rule.
If you want to associate a particular behavior and/or data with some DOM element, create a separate entity; it can be a full-blown class:
class ElementGreeter {
constructor(element, friendElement) {
this.element = element;
this.friendElement = friendElement;
}
greetFriend() {
this.greet(this.element.innerText);
}
greetFriend() {
this.greet(this.friendElement.innerText);
}
greet(message) {
alert(message);
}
}
… or a simple function:
const createGreeter = (propName) => (element) => alert(element[propName]);
const greet = createGreeter("innerText");
greet(element);
greet(friendElement);