Sprinkling Little Bits of Behavior Using JavaScript Modules
We often encounter scenarios where we need a small piece of (somewhat) simple functionality on a single page. After a successful 15-minute yak-shave-code-off, we've figured out a solid way to tackle this requirement.
THE PROBLEM
Initially, I wanted to prefix classes with .js-
to illustrate that our Javascript had dependencies on those DOM elements. It quickly became evident that this was a mistake - it caused the duplication of class names (save the .js-
prefix), and mixing that prefix with styling seemed dirty.
THE SOLUTION
After our code-off, and in essence generating code that was 98% identical, we settled on having a JavaScript module class name at the top level, and keeping general, descriptive class names for styling and interaction at lower levels. This saves us duplicate class names, but still alerts other developers to the fact that JavaScript utilizes classes within. This also allows us to transition to React or Backbone and have JavaScript build the elements within our module container.
Below is an example of an activator module for adding/removing items from an "active" list. (Try it out here)
THE CODE
HTML
<div class="js-item-activator">
<div class="item-list active">
</div>
<div class="item-list inactive">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
<div>
JavaScript
$(function() { var $module = $('.js-item-activator'); $('body').on('click', '.active .item', function() { var $item = $(this);$item.detach().appendTo($module.find('.inactive')); });
$('body').on('click', '.inactive .item', function() { var $item = $(this);$item.detach().appendTo($module.find('.active')); }); })
Sass
.item-list
background: #eee
border: 1px solid #ddd
margin-bottom: 10px
min-height: 30px
overflow: hidden
padding: 10px
.item
background: #ddd
border: 1px solid #ccc
cursor: pointer
float: left
margin-right: 10px
padding: 5px 10px