HW Accelerated Accordion
Translations-only, height-changes-free accordion for all your mobile needs.
HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
<title>HW Accelerated Accordion for iPhone / iPod Touch / Android / iPad</title>
<script type="text/javascript" src="accordion.js?v1"></script>
<script type="text/javascript">
var myAccordion;
function loaded() {
myAccordion = new accordion('accordion', true);
}
document.addEventListener('DOMContentLoaded', loaded, false);
</script>
</head>
<body>
<div id="accordion">
<div>
<div>First Law</div>
<div>A robot may not injure a human being or, through inaction, allow a human being to come to harm.A robot may not injure a human being or, through inaction, allow a human being to come to harm.A robot may not injure a human being or, through inaction, allow a human being to come to harm.A robot may not injure a human being or, through inaction, allow a human being to come to harm.A robot may not injure a human being or, through inaction, allow a human being to come to harm.A robot may not injure a human being or, through inaction, allow a human being to come to harm.A robot may not injure a human being or, through inaction, allow a human being to come to harm.A robot may not injure a human being or, through inaction, allow a human being to come to harm.</div>
</div>
<div>
<div>Second Law</div>
<div>A robot must obey any orders given to it by human beings, except where such orders would conflict with the First Law.</div>
</div>
<div>
<div>Third Law</div>
<div>A robot must protect its own existence as long as such protection does not conflict with the First or Second Law.</div>
</div>
<div>
<div>Zeroth Law</div>
<div>A robot may not harm humanity, or, by inaction, allow humanity to come to harm.</div>
</div>
<div>
...
CSS
<style type="text/css" media="all">
body {
padding:0;
margin:0;
border:0;
}
body {
font-size:16px;
-webkit-user-select:none;
-webkit-text-size-adjust:none;
font-family:georgia;
line-height:140%;
}
#accordion {
padding-bottom:200px;
}
#accordion > div {
width:100%;
}
#accordion > div > div:first-child {
-webkit-box-sizing:border-box;
width:100%; height:48px;
line-height:48px;
overflow:hidden;
white-space:no-wrap;
padding:0 10px 0 40px;
border-bottom:1px solid #888;
border-top:1px solid #eee;
background:url(arrow.png) 10px 50% no-repeat,
-webkit-gradient(linear, 0 0, 0 100%, from(#f4f4f4), to(#a0a0a0));
text-shadow:0 1px 0 #fff;
font-weight:bold;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
#accordion > div.acOpen > div:first-child {
background-position:-1014px 50%;
}
#accordion > div > div:last-child {
-webkit-box-sizing:border-box;
width:100%;
padding:10px;
background:#e3e3e3;
font-style:italic;
}
/* The followings are the only styles needed by the accordion */
#accordion {
position:relative;
}
#accordion > div {
position:absolute;
overflow:hidden;
}
#accordion > div > div:first-child {
position:relative;
z-index:11 !important; /* z-index can be any value greater than "div:last-child" z-index */
}
#accordion > div > div:last-child {
position:absolute;
z-index:10;
}
</style>
JavaScript
(function(){
function accordion (el, scroll) {
var that = this,
top = 0,
accordions, i, l;
that.el = document.getElementById(el);
that.scroll = scroll===true;
// Get the wrappers
that.wrappers = document.querySelectorAll('#' + el + ' > div');
// Get the headers
that.handles = document.querySelectorAll('#' + el + ' > div > div:first-child');
// Get the accordions
accordions = document.querySelectorAll('#' + el + ' > div > div:last-child');
// Assign default styles
for (i=0, l=that.wrappers.length; i<l; i++) {
that.wrappers[i].style.top = top + 'px';
that.wrappers[i].style.webkitTransitionProperty = '-webkit-transform';
that.wrappers[i].style.webkitTransitionTimingFunction = 'cubic-bezier(0,0,0.25,1)';
that.wrappers[i].style.webkitTransitionDuration = '0';
that.wrappers[i].style.webkitTransform = translateOpen + '0,0' + translateClose;
that.wrappers[i]._pos = i;
top += that.wrappers[i].offsetHeight;
}
that.el.style.height = top + 'px';
for (i=0, l=that.handles.length; i<l; i++) {
that.handles[i].addEventListener('click', that, false);
}
for (i=0, l=accordions.length; i<l; i++) {
accordions[i].style.webkitTransitionProperty = '-webkit-transform';
accordions[i].style.webkitTransitionTimingFunction = 'cubic-bezier(0,0,0.25,1)';
accordions[i].style.webkitTransitionDuration = '0';
accordions[i].style.webkitTransform = translateOpen + '0,0' + translateClose;
}
}
accordion.prototype = {
handleEvent: function (e) {
if (e.type == 'click') {
this.toggle(e);
} else if (e.type == 'webkitTransitionEnd') {
this.transitionEnd(e);
}
},
toggle: function (e) {
var that = this,
targetWrapper = e.currentTarget.parentNode,
targetHandle = targetWrapper.querySelector('div:first-child'),
...