Main features
- Lightweight (~2.2kB minified & gzipped version), yet robust (lot of options)
- No dependencies
- WAI ARIA compliant
Installation and usage
$ npm install collapsable.js --save
import Collapsable from 'collapsable.js'
new Collapsable(document.querySelector('.js-collapsable'))
Examples
Basic usage
Plugin will automatically create anchors inside the control elements as seen in first collapsable box. That is the simplest possible example. There could already be existing a link inside the control element. In that case, the plugin handlers all added to the existing anchor element. And lastly, the control class could be directly on the anchor element itself.
Similarly, when there is an existing id attribute, it is used for aria attributes and as an href attribute for the anchor. If there is no id, the plugin will create unique one.
Preview
Basic collapsable box
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lacinia lorem sit amet elit ullamcorper hendrerit. Pellentesque rhoncus eget sem in varius. Nulla congue lectus sed leo scelerisque scelerisque. Cras iaculis pulvinar velit. Proin ac lectus at elit tristique rhoncus. In pellentesque blandit feugiat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aenean at dictum purus. Sed non fringilla dolor.
Basic collapsable box #2
Nulla sit amet euismod nulla. Nunc tincidunt lectus eget felis volutpat, non scelerisque erat ornare. Phasellus vehicula ex eu tincidunt sodales. In hac habitasse platea dictumst. Donec tincidunt malesuada mi, vel sagittis arcu facilisis eget. Nam arcu ipsum, cursus sit amet purus vel, aliquet elementum dui. Nulla ultrices pulvinar velit, sit amet egestas est varius sed. Etiam tempor ex non porta porta. In interdum blandit urna ac vulputate. Nam facilisis arcu congue, fermentum enim vel, blandit mauris. Donec consectetur luctus volutpat.
Basic collapsable box #3
Curabitur sed orci at elit euismod euismod et ac sem. Phasellus mattis arcu vitae dapibus sagittis. Mauris sit amet dictum velit, vitae venenatis lectus. Donec velit nisi, laoreet vel risus iaculis, maximus cursus sem. Suspendisse potenti. Nulla molestie purus sit amet lectus varius consequat ac ut neque. Donec eu tincidunt ex. Maecenas cursus semper ex finibus eleifend. Nullam erat neque, elementum ac egestas sit amet, porttitor eget sem.
HTML
<div class="collapsable collapsable-basic">
<h4 class="js-collapsable__control"><i class="js-collapsable__icon" aria-hidden="true"></i> Basic collapsable box</h4>
<div class="js-collapsable__box">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lacinia lorem sit amet elit ullamcorper hendrerit. Pellentesque rhoncus eget sem in varius. Nulla congue lectus sed leo scelerisque scelerisque. Cras iaculis pulvinar velit. Proin ac lectus at elit tristique rhoncus. In pellentesque blandit feugiat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aenean at dictum purus. Sed non fringilla dolor.</p>
</div>
</div>
<div id="ca-1" class="collapsable collapsable-basic">
<h4 class="js-collapsable__control"><a href="#ca-1"><i class="js-collapsable__icon" aria-hidden="true"></i> Basic collapsable box #2</a></h4>
<div class="js-collapsable__box">
<p>Nulla sit amet euismod nulla. Nunc tincidunt lectus eget felis volutpat, non scelerisque erat ornare. Phasellus vehicula ex eu tincidunt sodales. In hac habitasse platea dictumst. Donec tincidunt malesuada mi, vel sagittis arcu facilisis eget. Nam arcu ipsum, cursus sit amet purus vel, aliquet elementum dui. Nulla ultrices pulvinar velit, sit amet egestas est varius sed. Etiam tempor ex non porta porta. In interdum blandit urna ac vulputate. Nam facilisis arcu congue, fermentum enim vel, blandit mauris. Donec consectetur luctus volutpat.</p>
</div>
</div>
<div id="ca-2" class="collapsable collapsable-basic">
<h4><a href="https://github.com/zipper/collapsable.js" class="js-collapsable__control">Basic collapsable box #3</a></h4>
<div class="js-collapsable__box">
<p>Curabitur sed orci at elit euismod euismod et ac sem. Phasellus mattis arcu vitae dapibus sagittis. Mauris sit amet dictum velit, vitae venenatis lectus. Donec velit nisi, laoreet vel risus iaculis, maximus cursus sem. Suspendisse potenti. Nulla molestie purus sit amet lectus varius consequat ac ut neque. Donec eu tincidunt ex. Maecenas cursus semper ex finibus eleifend. Nullam erat neque, elementum ac egestas sit amet, porttitor eget sem.</p>
</div>
</div>
JavaScript
const collapsableBasic = document.querySelectorAll('.collapsable-basic');
new Collapsable(collapsableBasic);
Accordion
Option accordion
specifies, that boxes are connected to each other and you may open only one at time, so there is always zero or one expanded box.
Preview
Accordion box 1
Aliquam vitae diam convallis lorem luctus maximus eget at massa. Sed lobortis cursus augue. Curabitur at pretium nibh. Integer ipsum risus, sagittis id leo ut, lobortis mollis nulla. Sed vehicula nisi vel erat tempus, id posuere arcu iaculis. Vestibulum vehicula cursus elementum. Vestibulum quis mi quis nisl placerat porttitor non ac magna. Cras erat diam, tincidunt non cursus a, hendrerit et enim. Maecenas consequat tellus et nisl condimentum fermentum. Aliquam luctus egestas maximus. Nam dictum viverra venenatis.
Accordion box 2
Fusce nibh magna, accumsan eu orci vitae, convallis facilisis enim. Proin leo urna, tristique vel consectetur quis, gravida non ante. Aliquam erat volutpat. Vivamus varius sapien sapien, eget blandit quam molestie ut. Fusce rutrum id sem quis dapibus. Nullam vel urna ac erat eleifend dapibus. Phasellus cursus volutpat purus, in fermentum mauris vulputate sed. Phasellus sagittis sem ex, sit amet consectetur felis luctus eu. Vestibulum elementum libero eu libero pharetra lobortis. Curabitur dignissim sapien ut est varius, ac sollicitudin nunc euismod. Duis augue justo, accumsan eget sapien eu, aliquet lobortis lacus.
Accordion box 3
Quisque lobortis dolor erat, eu interdum leo elementum in. Pellentesque placerat, ligula viverra laoreet imperdiet, urna augue dignissim nulla, nec finibus nisi urna sed nisi. Praesent viverra ornare arcu at luctus. Maecenas non nunc sapien. Nullam eget purus ornare, ultricies sapien sit amet, ullamcorper lacus. Proin id convallis quam. Duis nec tincidunt orci. In leo turpis, finibus at ex vitae, finibus maximus dolor. Praesent viverra eget metus id auctor. Nam semper sed urna in tempus. In eu ornare quam. Suspendisse quis ornare nibh.
HTML
Sample code is very similar to basic example, except the class on boxes is collapsable-accordion
. See source code for details if needed.
JavaScript
const collapsableAccordion = document.querySelectorAll('.collapsable-accordion');
new Collapsable(collapsableAccordion, {
accordion: true
});
Always at least one visible box
With collapsableAll
option is set to true, there will always be at least one expanded item – you won't be able to close all. You can combine this option with accordion
from previous example. That will result in exactly one expanded box all the time.
Preview
Non-collapsable-all box 1
Cras lacinia risus sem, rhoncus dictum tortor tincidunt in. Integer sit amet ex dui. Maecenas et dui metus. Fusce in ligula a libero pulvinar tempus.
Non-collapsable-all box 2
Integer non mollis quam. Ut dapibus sed dui eu elementum. Aliquam et neque erat. Duis commodo mauris nisl, vitae cursus urna convallis in.
Non-collapsable-all box 3
Sed feugiat dapibus euismod. Donec tristique condimentum urna eget maximus. Nulla scelerisque condimentum enim sed ornare. Etiam nec lacus sed justo lacinia efficitur.
HTML
Sample code is very similar to basic example, except the class on boxes is collapsable-collapsableAll
. See source code for details if needed.
JavaScript
const collapsableCollapsableAll = document.querySelectorAll('.collapsable-collapsableAll')
new Collapsable(collapsableCollapsableAll, {
collapsableAll: false
});
Options
Plugin exports type CollapsableOptions
which is used for options.
Option | Default Value | Type | Description |
---|---|---|---|
control | '.js-collapsable__control' |
String | CSS selector for control element. |
box | '.js-collapsable__box' |
String | CSS selector for box element. |
event | 'click' |
String | Event binded to control element. This event will trigger box expanding / collapsing. |
preventDefault | true |
Boolean |
Whether e.preventDefault() is called on event binded on control element. This
prevents browser from scrolling to anchor or navigating to link address. Alternatively, you
can call e.collapsableEvent.preventDefault() inside expand.collapsable
(collapse.collapsable ) handlers instead.
|
fxDuration | 0 |
Integer |
Defines the delay between expand (collapse ) and
expanded (collapsed ) events being triggered. It could be useful
when using CSS animations for expanding / collapsing boxes.
|
accordion | false |
Boolean | If set to true , only one box from set on which collapsable has been initialized could be opened at the same time. |
collapsableAll | true |
Boolean | Whether all box could be closed at the same time. If set to false , there is always at least one box from set opened. |
externalLinks | {…} |
Object | Object, see below |
selector | '' |
String | CSS selector for external links. Element matching the selector has to be an anchor element with href attribute set to corresponding collapsable item. On click, the collapsable item is toggled (expanded or collapsed based on current state). When falsy value is used, external links won't be searched for. |
preventDefault | false |
String |
When external links being used, by default the click event is not prevented, resulting in
scroll to the collapsable item. This can be prevented with setting this option to
true .
|
classNames | {…} |
Object | Object, see below |
link | '.js-collapsable__link' |
String | CSS class assigned to control link elements (both created or present in time of initialization). |
expanded | '.js-collapsable--expanded' |
String | CSS class assigned by script to expanded items. Added to element on which the Collapsable() has been called. |
collpased | '.js-collapsable--collapsed' |
String | CSS class assigned by script to collapsed items. Added to element on which the Collapsable() has been called. |
defaultExpanded | '.js-collapsable--default-expanded' |
String | Items with this class in HTML will be expanded by default after collapsable initialization. |
externalLinkActive | '.js-collapsable-ext-link--active' |
String | When collapsable item is expanded, external links associated with it recieves this class. |
Events
Old documentation for 2.0.8! Information down there are still somewhat correct, but with slightly different syntax.
Events triggered by plugin itself
Since version 2.0.0, there is no possibility to pass callback functions via options. Instead, you may bind handlers
to events which are triggered by plugin. All events are namespaced (collapsable
). In table below,
there are all events which might be triggered by plugin. In all events, this
refers to collapsable box
from initial set.
Event name | Description |
---|---|
expand.collapsable | Event triggered when box is about to expand. You can prevent it from expanding either using e.preventDefault() or by returning false (which also stops the event propagation). |
expanded.collapsable | When box is fully expanded, this event is triggered. If you use jQuery function or custom function, it is triggered as a callback of those functions. Otherwise, it is called after fxDuration milliseconds. |
collapse.collapsable | Analogical to expand.collapsable . |
collapsed.collapsable | Analogical to expanded.collapsable . |
destroy.collapsable | When the collapsable is destroyed, elements are returned to their state prior to initialization and on each of them, this event is triggered. |
Possible events passed in e.collapsableEvent
Each event from above may contain property collapsableEvent
. This allows you to distinguish actions that
led to expansion or collapse of the box, eg. if this expands by user click or any other way. Possible events stored
in are in table below. Additionally, when data has been passed to event (eg. by calling .collapsable('collapseAll', data)
),
property customData
is set in event.
Event name | Description |
---|---|
init.collapsable | After initialization, expand.collapsable and collapse.collapsable are triggered on each item accordingly. Original event is set to this value. |
expandAll.collapsable | When method .collapsable('collapseAll') is called on set of collapsable elements. Event is triggered only on items, that actually do expand. |
collapseAll.collapsable | Analogical to expandAll.collapsable . |
click.collapsable | Original event is set to this value when the user clicks on control element (if option event === 'click' ) or if external link is clicked. Whole original jQuery event object is passed, so yo may use standard jQuery (and JS) functions for events. |
event.collapsable | Where "event" refers to actual name of event which has been set in options, eg. touchstart.collapsable . Same as previous, it is jQuery event object. |
Public methods
After initialization, you may use a few public methods defined on carousel. There are three public methods defined,
expandAll
, collapseAll
and destroy
which will return the
DOM into state prior to initialization. All methods might be called on any collapsable
item (in that case, the initial set is found), whole set or even multiple sets.
// collapses all items from set $('.collapsable')
$('.collapsable').collapsable('expandAll');
// this will also expand all items from set, even though it has been called only on one item
$('.collapsable').get(0).collapsable('expandAll');
// collapses all items from set $('.collapsable') and from $('.collapsable-2')
$('.collapsable, .collapsable-2').collapsable('collapseAll');
// destroys collapsable and returns DOM to state prior to initialization
$('.collapsable').collapsable('destroy');
There is a data set on each item containing JS Object. You may retrieve it and then use some other functions defined on objects itself. See example below.
// get the instance of CollapsableItem object
var item = $('.collapsable').eq(0).data('collapsable');
/**
* Expand this item, arguments of function call are
* @param event - event passed to handler of triggered events (expand.collapsable, ...)
* @param data - data passed to event, accessible in event.customData
* @param force - boolean for expanding item regardless of event.preventDefault call in expand.collapsable handler
* @returns Boolean - if the item has or has not been expanded
*/
item.expand(event, data, force);
// Collapse the item, analogical to above
item.collapse(event, data, force)
// instance of Collapsable object, contains array items, where there are all items as CollapsableItem
var set = item.parent;
// Expands all items of set, data are passed expand.collapsable handler in e.customData
set.expandAll(data);
// Analogical, but collapses all items
set.collapseAll(data);
Changelog
2.0.8
- added control if hash in url is valid selector, eg.
#_=_
is would cause jQuery to throw an error
2.0.7
- when collapsable control anchor is present in HTML and its href attribute is
#
, then it is replaced with collapsable box id
2.0.6
- fixup: default expanded box could have been ignored under certain circumstances
2.0.5
- there could be more than one box per collapsable element, id's are suffixed with index of the box and
aria-controls
attribute is changed appropriately
2.0.4
- fixes #10 (empty hash
#
in url causes JS error in jQuery 3 when used as selector$('#')
)
2.0.3
- fixed JS error when called on empty jQuery object with
collapsableAll: false
set - fixes #7 - items are properly collapsed on initialization when combination of
collapsableAll
andaccordion
is used - fixes #8
2.0.2
- renamed property
tooriginalEvent
collapsableEvent
, sopreventDefault
called onexpand.collapsable
orcollapse.collapsable
event doesn't prevent that custom event as well
2.0.1
- renamed option
to more recognizablegrouped
accordion
- changed default
fx
value tonull
for no effect used - changed order of executing
fx
function and class assigning so it doesn't interfere with jQuery effects - default value of
extLinks.selector
to empty string''
- move class name option for active external links into
classNames
- destroy function now actually works properly :) some optimizations were done to destroy method apart from making it work
- when destroy is called, aria attributes are removed as well - #6
isExpanded
is not a method anymore- bugfix of not binding event on control element if it is anchor
2.0.0
- plugin has been completely rewritten