Storing Arbitrary Info in HTML Tags for JavaScript

Storing arbitrary info in HTML tags for JavaScript?

You could find out which tabbed element a field belongs to by writing an isChildOf function, like this: http://jimkeller.blogspot.com/2008/07/jquery-ischildof-is-element-child-of.html

Using the DOM to work this out will always be more "elegant" than duplicating the data in some custom format.

How to store arbitrary data for some HTML tags

Which version of HTML are you using?

In HTML 5, it is totally valid to have custom attributes prefixed with data-, e.g.

<div data-internalid="1337"></div>

In XHTML, this is not really valid. If you are in XHTML 1.1 mode, the browser will probably complain about it, but in 1.0 mode, most browsers will just silently ignore it.

If I were you, I would follow the script based approach. You could make it automatically generated on server side so that it's not a pain in the back to maintain.

Storing arbitrary data in HTML

HTML5 now supports the data-name syntax for storing abitrary data without non-standard custom attributes

This will of course break validation if your doctype is anything other than HTML5 (although there are ways around this) but it wont affect the rendering or parsing in any browsers I've come across.

Here is an excellent article by John Resig on the matter

Should I avoid adding arbitrary fields to HTML elements?

EDIT

I just learned about Custom Events that can be used to add custom handlers to elements.



Previous Answer

Most of the answers to this question have these two parts:

  1. Why storing none DOM data in DOM elements is wrong?
  2. What is the alternative solution?

Originally I was looking for the first part only, then reading more about second part, found out it is really important to consider alternative solutions to make the decision. I will also include these two parts in my answer.

Why storing none DOM data in DOM elements is wrong?

Many people may start learning web development with HTML, then move to CSS and JS. This make them see the HTML as the back bone of the web app, that CSS and JS are plugged here and there to it. When designing the logic of the application around the HTML elements, storing non-visual data at DOM elements makes total sense and it seems very unfair to find out that JS objects and functions cannot be referenced there.

The alternative and correct view is to see the HTML and CSS and JS as three independent pillars of the app that have some ways of communication. Each pillar should encapsulate the data it needs for its internal work. DOM elements are there to tell browsers how to render the page. They shouldn't be used as a referencing point to address data used by JS.

What is the alternative solution?

The supported solutions are:

  1. Using global objects
  2. Serializing into DOM elements' dataset

The unsupported solutions are:

  1. Adding arbitrary fields to DOM elements (works with functions too!)

Each one of these solutions have their own problems (I won't go to details here), so I ended up using another solution:

Capturing

I need to rephrase the problem to explain this.
The problem is that the scope that objects are defined is different than the scope they are needed.

Capturing helps teleport objects from one scope to another scope. To apply this solution, we need to design a hierarchy of scopes in a way that each scope have access to all external objects it needs via its parent scope(s). Here is an example:

Problem:

<script>
window.onload = () => {
let message = 'Hello, world!';
// Need to reference message within greet function
// element's dataset or global object will work
};
function greet() {
alert(message); // where to find it?
}
</script>
<button onclick='greet()'>Greet</button>

Solution:

<script>
window.onload = () => {
let message = 'Hello, world!';
document.getElementById('greeter').onclick = function() {
alert(message); // capture it
};
};
</script>
<button id='greeter'>Greet</button>

As you see, I've moved the onclick function into onload function to steal objects from its scope.

Is it best practice to store data in HTML tags that don't have any content?

It is designed for this in HTML5.
More about data-* here: http://www.w3schools.com/tags/att_global_data.asp

Alternatively you could do:

<script>
var store = {
"myStoreId": 1234,
"myOterStoreId": 9876,
}
</script>

Access it by:

store["mystoreId"]

or

for (storeId in store) {
var idNumber = store[storeId]
}

EDIT: Maybe you simple want an Array of "storeIds" ? Do it like that:

<script>
var store = [
1234,
9876,
]
</script>

Access it by:

store[index]

or

for (var i = 0; i < store.length; ++i) {
var idNumber = store[0]
}

A HTML tag to store javascript's data?

Creating Custom tag

var xFoo = document.createElement('placeholder');
xFoo.innerHTML = "TEST";
document.body.appendChild(xFoo);

Output:

<placeholder>TEST</placeholder>

DEMO

Note: However creating hidden input fields with unique ID is good practice.

php: the best way to store data of arbitrary html elements in html to pass this data to innerHTML of elements on a HTML-page?

Just store the HTML as a (properly-escaped) string:

var foo = document.getElementById("foo"),
html = "<img src='http://placekitten.com/100/100' onclick='alert(1);' />";

if (foo.addEventListener) {
foo.addEventListener("click", setInner, false);
} else if(foo.attachEvent) {
foo.attachEvent("onclick", setInner);
}

function setInner () {
foo.innerHTML = html;
}​

Demo: http://jsfiddle.net/UAL8P/

Adding arbitrary information to createElement object

You can use the html5 data attribute to add arbitrary data to DOM elements.

btn.setAttribute('data-array','one,two,three');

Get the data back by using split;

Here's an example: jsFiddle

What is the purpose of storing custom data on HTML data attributes?

One use case I currently used was I created a component in react and used pseudo elements to take data from data attribute ie. data-title value will be taken by CSS in content: attr(data-title) so what ever value I am passing to component shows directly via css and also there are so many use cases for eg you need some value to be instead of passing whole object on click function you just add click event and it will take values from data attributes instead.

These two use cases I can think of rite now.

----------- UPDATE ---------------

data-* attributes allow us to store extra information on standard, semantic HTML elements without other hacks such as non-standard attributes, or extra properties on DOM, hacks can make your HTML invalid in many cases or create unknown bugs. Common attributes that we use are class, id etc and for custom attributes you can use data-*. The main motivation behind introduction of data attribute is to allow us to store extra information on standard, semantic HTML elements without other hacks such as non-standard attributes, or extra properties on DOM. So when you ask what's better approach you, all you can think about is there are multiple ways to achieve same thing and it's subjective to developer to take approch.

Best way to add metadata to HTML elements

Go ahead and use an attribute for this, but use a data- prefix on it. Attributes with the prefix data- are explicitly allowed on all elements as of HTML5. Example:

<a href="#" class="Theme-Button" data-theme="{style: 'win2007', icon: 'left', align:'center', fullWidth: true}"></a>

It works today in all browsers, and because it's now specified behavior, it's future-proofed.



Related Topics



Leave a reply



Submit