One of my favorite but often overlooked features of jQuery is the data method, which allows you to associate specific data to a DOM element. This is particularly useful when dealing with a list of elements which have a lot of metadata. Without the data method, you could do this by storing everything in an array or adding funky attributes to an element, but that can get fairly convoluted. Not a lot of developers are aware of the power of jQuery data, so this post will cover a basic use case.

Let’s say we have a site which has a list of blog posts on the left-hand side. When one is clicked, the right side is populated with the blog post contents. The interaction is very similar to what we’ve done on the pulse.me site, where we use jQuery data for storing information about a story. The template fields in the HTML below would be populated using a templating framework.

HTML:

    <ul id="blog-posts">
        <li id="blog-post-0" class="blog-post-item">
            <h1>{{ post_title }}</h1>
            <h2>{{ post_date }}</h2>
            <h3>{{ post_author }}</h3>    
            <p>{{ post_snippet }}</p>
        </li>
    ...
    </ul>
   
    <article id="blog-post">
        <section id="blog-post-header">
            <h1>{{ post_title }}</h1>
            <h2>{{ post_date }}</h2>
            <h3>{{ post_author }}</h3>
            <h4>{{ post_category }}</h4>
        </section>
        <section>
            <img alt="{{ post_image_caption }}" src="{{ post_image }}"
           <p id="blog-post-content">{{ post_content }}</p>
            <span id="blog-post-tags">{{ post_tags }}</span>
        </section>
    </div>

Once we have the json object with the post data, we can save it. An association is made to the <body> and the <li> id in the DOM. The id is used as a key to reference the post’s data.

JavaScript:

Update: Thanks to the Hacker News community (Xurinos, rimantas) for some tips on improving performance. See commented out lines for old and less optimal code.

    // Post data
    var post = {
        'post_title' : '125 Days at a Startup',
        'post_date' : '2011/06/21 10:00:00 -0700',
        'post_author' : 'Filip Mares',
        'post_category' : 'Pulse',
        'post_tags' : 'experience, startups, updates'
        'post_image' : 'http://posterous.com/getfile/files.posterous.com/temp-2011-06-20/koJbhHJJHJgDmpxbrshCjdDoFsktnbmoJspkkIJgBoDJqyFwcxIFpIGgHsti/IMG_0385.JPG.scaled1000.jpg',
        'post_image_caption' : '125 Days at a Startup',
        'post_content' : 'This is the content...',
        'post_snippet' : 'This is the snippet...',
        'post_url' : 'http://filipmares.com/125-days-at-a-startup'
    }

    $(document).ready(function ()
    {
        // id of &lt;ul&gt; node
        var blog_post_id = 'blog-post-0';

        //Saving the incoming data in association to the
        //$('body').data(blog_post_id, post);
        $.data(document.body, blog_post_id, post)
       
        // Function for appending post data to list of posts
        PopulatePostsList(post);
    });

In order to query the post from memory we bind a click event function to retrieve the contents for the <li> id in question. Afterwards, we call a function that uses a templating framework to populate the DOM according to the HTML above. The ‘DeletePost()’ method is an example of how to delete the data from memory.

JavaScript:

Update: Thanks to the Hacker News community (Xurinos, rimantas) for some tips on improving performance. See commented out lines for old and less optimal code.

// Retrieve posts data on list element click
$('.blog-post-item').click(function(){

    //var id = $(this).attr('id');
    var id = this.id;
    var post = $.data(document.body, blog_post_id, post);
   
    // Function that outputs post data to article on DOM
    PopulatePost(post);
    });
   
    // Delete post with id passed
    DeletePost(blog_post_id){
    try{
        // Remove post from memory and terminate association
        //$('body').removeData(id);
        $.removeData(document.body, id)
    }catch(err){
        console.error('Post does not exist')
    }
}

Although this is fairly straightforward, please keep a few things in mind; this is not an alternative to local storage and can potentially lead to memory leaks when dealing with a lot of stored data. Be responsible when using the call and remove data that isn’t being used anymore. Furthermore, storing data takes a certain amount of time, so you might get a null exception if you are planning on retrieving it right after storage. There are currently no plans to add a callback to the jQuery data that I’m aware of.

Happy coding,

Filip