Home > other >  Should I avoid adding arbitrary fields to HTML elements?
Should I avoid adding arbitrary fields to HTML elements?

Time:12-29

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:

  1. Do all the major browsers support this behavior?
  2. 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?
  3. 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);
  • Related