Created
June 11, 2019 18:48
-
-
Save stewartknapman/ff9f52b97fab157285b2aa94903a7e9b to your computer and use it in GitHub Desktop.
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
(function () { | |
if (!document.querySelector && !window.addEventListener && !("classList" in document.createElement("p"))) return; | |
var ready = function (callback, ctx) { | |
if (typeof callback !== 'function') return; | |
if (document.readyState !== "loading") { | |
callback.apply(ctx); | |
} else { | |
document.addEventListener("DOMContentLoaded", function () { | |
callback.apply(ctx); | |
}); | |
} | |
}; | |
var each = function (arr, callback, ctx) { | |
var r; | |
for (var i = 0; i < arr.length; i++) { | |
ctx = ctx || arr[i]; | |
r = callback.apply(ctx, [arr[i], i]); | |
if (r == false) break; | |
} | |
}; | |
var debounce = function (callback, wait, ctx) { | |
var timeout, timestamp, args; | |
wait = wait || 100; | |
var later = function() { | |
var last = new Date().getTime() - timestamp; | |
if (last < wait && last >= 0) { | |
timeout = setTimeout(later, wait - last); | |
} else { | |
timeout = null; | |
callback.apply(ctx, args); | |
} | |
}; | |
return function () { | |
ctx = ctx || this; | |
args = arguments; | |
timestamp = new Date().getTime(); | |
if (!timeout) timeout = setTimeout(later, wait); | |
}; | |
}; | |
/* Accordian Main */ | |
var Accordian = function (ele, selectors) { | |
this.classes = { | |
open: 'accordion__section--open' | |
}; | |
this.selectors = selectors; | |
this.ele = ele; | |
this.sections = this._getSections(); | |
this._setContentHeights(); | |
this._addEventListeners(); | |
}; | |
Accordian.prototype.toggleSection = function (target) { | |
var targetEle = this.ele.querySelector(target); | |
var currentSection = targetEle.closest(this.selectors.sections); | |
var isclosed = true; | |
if (currentSection.classList.contains(this.classes.open)) { | |
isclosed = false; | |
} | |
this.closeSections(); | |
if (isclosed) { | |
var content = currentSection.querySelector(this.selectors.content); | |
currentSection.classList.add(this.classes.open); | |
content.style.height = content.getAttribute('data-height'); | |
} | |
}; | |
Accordian.prototype.closeSections = function () { | |
each(this.sections, function (section) { | |
var content = section.querySelector(this.selectors.content); | |
content.style.height = '0'; | |
section.classList.remove(this.classes.open); | |
}, this); | |
}; | |
Accordian.prototype._addEventListeners = function () { | |
var _this = this; | |
this.actions = this.ele.querySelectorAll(this.selectors.actions); | |
each(this.actions, function (action) { | |
action.addEventListener('click', function (e) { | |
var target = e.currentTarget.getAttribute('href'); | |
e.preventDefault(); | |
_this.toggleSection(target); | |
}); | |
}); | |
window.addEventListener('resize', debounce(function () { | |
_this._setContentHeights(); | |
})); | |
}; | |
Accordian.prototype._getSections = function () { | |
var sectionClassName = this.selectors.sections.replace('.',''); | |
if (this.ele.classList.contains(sectionClassName)) { | |
return [this.ele]; | |
} else { | |
return this.ele.querySelectorAll(this.selectors.sections); | |
} | |
}; | |
Accordian.prototype._setContentHeights = function () { | |
var contents = this.ele.querySelectorAll(this.selectors.content); | |
each(contents, function (content) { | |
var transition = window.getComputedStyle(content).transition; | |
var currentHeightStyle = window.getComputedStyle(content).height; | |
content.style.transition = 'none'; | |
content.style.height = 'auto'; | |
content.setAttribute('data-height', content.offsetHeight+'px'); | |
content.style.height = currentHeightStyle; | |
content.style.transition = transition; | |
}); | |
}; | |
// Plural | |
var Accordians = function () { | |
this.selectors = { | |
ele: '[data-accordion]', | |
sections: '.accordion__section', | |
content: '.accordion__content', | |
actions: 'a' | |
} | |
this.init(); | |
}; | |
Accordians.prototype.init = function () { | |
this.eles = document.querySelectorAll(this.selectors.ele); | |
if (!this.eles.length) return; | |
each(this.eles, function (ele) { | |
new Accordian(ele, this.selectors); | |
}, this); | |
}; | |
// Run everything | |
ready(function () { | |
new Accordians(); | |
}); | |
})(); |
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
<div class="accordion" data-accordion> | |
<!-- Start section --> | |
<div class="accordion__section accordion__section--features accordion__section--open"> | |
<div class="accordion__header"> | |
<h3> | |
<a href="#section1"> | |
Section 1 title | |
{% include 'icon-plus' %} | |
{% include 'icon-minus' %} | |
</a> | |
</h3> | |
</div> | |
<div class="accordion__content" id="section1"> | |
<ul class="rte"> | |
Section 1 content | |
</ul> | |
</div> | |
</div> | |
<!-- End section --> | |
</div> |
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
.accordion { | |
margin-bottom: $grid-gutter; | |
border-bottom: $color-border solid 1px; | |
ul { | |
padding-left: 1.25em; | |
} | |
} | |
.accordion__header { | |
padding-top: 1.5em; | |
border-top: $color-border solid 1px; | |
a { | |
display: block; | |
} | |
.icon { | |
float: right; | |
.no-js & { | |
display: none !important; | |
} | |
} | |
.icon-plus { | |
display: block; | |
.accordion__section--open & { | |
display: none; | |
} | |
} | |
.icon-minus { | |
display: none; | |
.accordion__section--open & { | |
display: block; | |
} | |
} | |
} | |
.accordion__content { | |
overflow: hidden; | |
.js & { | |
height: 0; | |
transition: .2s height ease-in-out; | |
} | |
.no-js &, | |
.accordion__section--open & { | |
height: auto; | |
margin-bottom: 1.5em; | |
} | |
} |
Where are the icon include files?
This was based on the Debut theme which has icons in the snippets folder. You can aways replace the icon includes with your own icons or svg
I have the opposite problem in that all the tabs are open when loaded, then once tab is clicked they resume correct behaviour. I'm really struggling to see why it's doing this.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can this change accordion change to all close and only open when its click?
like your previous accordion