Doing some work where using jQuery was verboten this (Ridiculously simple accordion without the jQuery UI library) was found.
It still used jQuery though so rolled my own. This markup:
<div id="accordion"> <h4 class="accordion-toggle">Accordion 1</h4> <div class="accordion-content default"> <p>Cras malesuada ultrices augue molestie risus.</p> </div> <h4 class="accordion-toggle">Accordion 2</h4> <div class="accordion-content"> <p>Lorem ipsum dolor sit amet mauris eu turpis.</p> </div> <h4 class="accordion-toggle">Accordion 3</h4> <div class="accordion-content"> <p>Vivamus facilisisnibh scelerisque laoreet.</p> </div> </div>
With this CSS:
.accordion-toggle { cursor: pointer; } .accordion-content { display: none; } .accordion-content.default { display: block; }
And with this Javascript (Polyfill added):
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Polyfill if (!Array.prototype.filter) { Array.prototype.filter = function(fun/*, thisArg*/) { 'use strict'; if (this === void 0 || this === null) { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; if (typeof fun !== 'function') { throw new TypeError(); } var res = []; var thisArg = arguments.length >= 2 ? arguments[1] : void 0; for (var i = 0; i < len; i++) { if (i in t) { var val = t[i]; // NOTE: Technically this should Object.defineProperty at // the next index, as push can be affected by // properties on Object.prototype and Array.prototype. // But that method's new, and collisions should be // rare, so use the more-compatible alternative. if (fun.call(thisArg, val, i, t)) { res.push(val); } } } return res; }; } (function() { "use strict"; // Stolen from: https://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/ var forEach = function(array, callback, scope) { for (var i = 0; i < array.length; i++) { callback.call(scope, i, array[i]); } }, accordion = document.getElementById("accordion"), toggles = accordion.querySelectorAll(".accordion-toggle"), greedy = false; forEach(toggles, function(i, v) { v.addEventListener("click", function() { var content = this.nextElementSibling; var classes = content.className.split(" "); if (classes.indexOf("default") !== -1) { content.className = classes.filter(function(value){ return value !== "default" }).join(" "); } else { if (greedy) { forEach(toggles, function(i, toggle) { var ct = toggle.nextElementSibling; var cs = ct.className.split(" "); ct.className = cs.filter(function(value){ return value !== "default" }).join(" "); }); } content.className += " default"; } }, false); }); })();
Does all that I need except for the animation - but I'll get there yet!
Working example here.