Skip to main content Skip to secondary navigation Accessibility Feedback

Setting multiple JavaScript plugin options with a single data attribute

Update: After a chat with Todd Motto, I’ve updated my approach.

All of my native JS plugins let users pass in options during initialization. For some (like Smooth Scroll and Jellyfish), I also provide a way for developers to override these options an item-by-item basis using data attributes.

Developers simply pass in all of their overrides via a single data-options attribute rather than forcing developers to use a data attribute for every option they want to change. Foundation uses this approach in several of their scripts.

// This
data-options="speed: 500; 
              easing: easeInOutCubic; 
              offset: 0; 
              updateURL: false"; 

// Instead of this
data-speed="500" 
data-easing="easeInOutCubic" 
data-offset="0" 
data-updateURL="false" 

To do this, I wrote a simple helper function that converts the contents of the data-options attribute into an object.

Psst... I'm writing a book on ditching jQuery for vanilla JS. Pre-order it today and save 50%.

data-options.js #

/**
 * Convert data-options attribute into an object of key/value pairs
 * @private
 * @param {String} options Item-specific options as a data attribute string
 * @returns {Object}
 */
var getDataOptions = function ( options ) {
    var settings = {};

    // Trim whitespace from a string
    var trim = function ( string ) {
        return string.replace(/^s+|s+$/g, '');
    };

    // Create a key/value pair for each setting
    if ( options ) {
        options = options.split(';');
        options.forEach( function(option) {
            option = trim(option);
            if ( option !== '' ) {
                option = option.split(':');
                settings[option[0]] = trim(option[1]);
            }
        });
    }

    return settings;
};

Example #

Markup

<a 
class="example" 
href="#" 
data-options="speed: 500;
              easing: easeInOutCubic;
              offset: 0;
              updateURL: false"; 
>
    link
</a>

JavaScript

var item = document.querySelector('.example');
var options = getDataOptions( item ? item.getAttribute('data-options') : null );

console.log(options);
// Returns: Object{speed: 500, easing: easeInOutCubic, offset: 0, updateURL: false}

See it in action in Smooth Scroll.

Update #

Todd Motto pointed out the dangers of using this approach:

data-json

All values, even numbers and booleans, are converted to strings. His solution is to use real JSON in your markup:

Markup

<a class="example" href="#" data-options='{
    "speed": 500,
    "easing": "easeIn OutCubic",
    "offset": 0,
    "updateURL": false
}'>link</a>

JavaScript

var getDataOptions = function ( options ) {
    return (!options || typeof JSON.parse !== 'function') ? {} : JSON.parse(options);
};

var item = document.querySelector('.example');
var options = getDataOptions( item ? item.getAttribute('data-options') : null );

console.log(options);

I’ll be updating my scripts accordingly.

If you liked this article, you might also like Ditching jQuery, my new beginner's guide to vanilla JavaScript. Pre-order it today and save 50%.
  • More articles on...
  • Code

Have any questions or comments about this post? Email me at chris@gomakethings.com or contact me on Twitter at @ChrisFerdinandi.

Get Weekly Digests