Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for storing data in a dom element (1 json or multiple data- attributes)

Tags:

json

html

jquery

I have a list of 4 articles (with small photo) and a place for 1 article with a bigger photo. When I click an article I will use javascript to display that small article in the big place.

To display the the article with bigger photo there are 3 things I have to know of the article: title, detailUrl and photoUrl (of the bigger photo), I want to catch this with javascript.

Methode 1: using jQuery .find() to search the DOM

$("#small").find('img').attr('src');

Methode 2: storing everything in seperate data attributes:

data-title="titel1" data-detailurl="article1.html"

Methode 3: Storing a JSON string

data-json="{ "title": "titel1", "detailurl": "article1.html" }"

I think the 3th methode is the best (fastest?). Is that right?

Here the html: http://jsfiddle.net/kHbZU/

like image 481
JeroenVdb Avatar asked Jan 16 '12 13:01

JeroenVdb


People also ask

Can an element have multiple data attributes?

A data attribute is a custom attribute that stores information. Data attributes always start with “data-” then followed with a descriptive name of the data that is being stored. You can have multiple data attributes on an element and be used on any HTML element.

In what format is the data stored in DOM?

The Document Object Model (DOM) is a programming API for HTML and XML documents.

What are data attributes good for?

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.

What are data attributes?

In short, a data attribute is a single-value descriptor for a data point or data object. It exists most often as a column in a data table, but can also refer to special formatting or functionality for objects in programming languages such as Python.


3 Answers

What about jQuery.data ?

I think it is better then all options.

    $.data(document.body, "sortElement", "0"); //set value
    $.data(document.body, "sortElement");        //read value
like image 44
Royi Namir Avatar answered Nov 16 '22 02:11

Royi Namir


Method three is easiest to work with of the ones you listed. Don't worry about the efficiency of string conversion. You'd have to have millions of articles for that to make a real difference. Keep in mind that if you are building this HTML on the server, the JSON will have to be encoded for the HTML to be valid. You can base-64 encode with .btoa()/.atob() to do this easily. If the .dataset property is used to set the data on the DOM, the DOM takes care of storing it properly as an object.

A fourth option is to use a <pre> block with display: none;. This works well if you're building your list on the server. I use this method on the tumblr theme I wrote, http://stiff-theme.tumblr.com/, because I had very little control over the server output. You can leave your JSON unencoded and convert it to to an object easily with $.parseJSON().

HTML:

<pre>
    { "title": "titel1", "detailurl": "article1.html" } 
</pre>

Script:

var articles = $.parseJSON( $( 'pre' ).text() );

A fifth method is to just use HTML markup and CSS to style. Create your markup of the large version of your article that contains everything. Then use a class to hide, resize, and position for your smaller list display. I like this method best for the problem you're trying to solve.

Demo: http://jsfiddle.net/ThinkingStiff/ngE8s/

HTML:

<ul id="articles">
    <li>
        <article>
            <img src="large-image-url.png">
            <h1>Title</h1>
            <section>
                <p>article body</p>
                ...

            </section>
        </article>
    </li>
    ...

</ul>

<div id="display"><div>

CSS:

#articles {
    display: inline-block;
    list-style-type: none;
    padding: 0;
    margin: 0;
    vertical-align: top;
    width: 200px; 
}

#articles li {
    border-bottom: 1px solid lightgray;
    cursor: pointer;
    display: block;  
    height: 32px;
    overflow-y: hidden;
}

#articles img {
    float: left;
    height: 30px;
    margin-right: 4px;
    width: 30px;    
}

#articles h1 {
    font-size: 13px;
    margin: 0;
}

#display {
    display: inline-block;
    vertical-align: top;
    width: 400px;
}

#display img {
    float: left;
    height: 150px;
    margin-right: 8px;
    width: 150px;    
}

#display h1 {
    margin: 0;    
}

p {
    font-size: 18px;
}

Script:

document.getElementById( 'articles' ).addEventListener( 'click', function( event ) {
    var article = event.target.closestByTagName( 'article' );

    if( article ) {
        var display = document.getElementById( 'display' ),
            large = article.cloneNode( true );
        display.removeChild( display.firstChild );
        display.appendChild( large );
    };
}, false );

Element.prototype.closestByTagName = function ( tagName ) {
    return this.tagName && this.tagName.toUpperCase() == tagName.toUpperCase()
        ? this
        : this.parentNode.closestByTagName && this.parentNode.closestByTagName( tagName );
};

Output:

enter image description here

like image 104
ThinkingStiff Avatar answered Nov 16 '22 02:11

ThinkingStiff


Best way would be to use data-xxx attributes. That's what it's meant for.

Just remember you can't use non-utf8 characters in data-xxx attributes. If it's too much data, or content data, I suggest to store an idreference like

<img data-content="#description"/>

and have a

<p id="#description">some more content with &aacute;ccents</p>

Hope it adds to the question.

Greetings, Bart.

like image 43
Bart Calixto Avatar answered Nov 16 '22 01:11

Bart Calixto