Last active
July 12, 2020 07:42
-
-
Save neodigm/61ef246d89121e7a8453d349746d5f10 to your computer and use it in GitHub Desktop.
Simple Vanilla JavaScript Expand and Collapse (async). Summary and Details paired elements 1:1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var oSimpleExpand = (function( doc ){ // Simple expand / collapse | |
var aSum, aDet; // Summary and Details paired elements 1:1 | |
return { | |
"rebind": function(){ | |
aSum = [].slice.call( doc.querySelectorAll("[data-expand-summary]") ); | |
aDet = [].slice.call( doc.querySelectorAll("[data-expand-details]") ); | |
aSum.forEach( function( aE ){ | |
var aDecl = aE.dataset.expandSummary.split("|"); | |
if( aDecl.length > 0 ){ | |
aE.aDecl = aDecl; | |
aE.eDet = aDet.filter( function( eDet ){ // match | |
if( eDet.dataset.expandDetails == aDecl[0] ){ return true; } | |
})[0]; | |
aE.removeEventListener( "click", oSimpleExpand.click ); | |
aE.addEventListener( "click", oSimpleExpand.click ); | |
} | |
}); | |
}, | |
"click": function( ev ){ // hide or show | |
var eDet = this.eDet; | |
var aDecl = this.aDecl; | |
if( eDet.classList.contains("hide") ){ | |
eDet.classList.remove("hide"); | |
if( aDecl[1] ) this.classList.add( aDecl[1] ); | |
if( aDecl[2] ) { // swap temp | |
aDecl[3] = this.innerHTML; | |
this.innerHTML = aDecl[2]; | |
} | |
}else{ | |
eDet.classList.add("hide"); | |
if( aDecl[1] ) this.classList.remove( aDecl[1] ); | |
if( aDecl[3] ) this.innerHTML = aDecl[3]; // undo | |
} | |
ev.preventDefault(); | |
} | |
} | |
})( document ); |
Ands its declarative.
Simplified Vue.js version:
**@click.prevent="doSimpleExpand('navBtnContent_1')"
doSimpleExpand( nameContent ){ // Expand or Collapse on existence in array
if( this.vueSimpleExpand.includes( nameContent ) ){ // Collapse
this.vueSimpleExpand = this.vueSimpleExpand
.filter( item => (item !== nameContent) );
}else{
this.vueSimpleExpand.push( nameContent ); // Expand
}
}
Please and some A11Y attributes | aria-controls, aria-expanded, aria-haspopup, and ...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is significant about this solution is that it can rebind well after the page has loaded. This is good for regions that get populated via AJAX (xhr, fetch). Also it maintains the state of the actual label text so for example a element might display the words either CLOSE or OPEN.