Skip to content

Instantly share code, notes, and snippets.

@killercup
Created December 17, 2015 09:34
Show Gist options
  • Save killercup/b1793dcf9e9dc5889590 to your computer and use it in GitHub Desktop.
Save killercup/b1793dcf9e9dc5889590 to your computer and use it in GitHub Desktop.
window.jQuery(function accordion($) {
var $root = $('html, body');
var ANIMATION_SPEED = 300;
var HEADER_HEIGHT_TALL = 220;
var HEADER_HEIGHT_SMALL = 70;
var SMALL_HEADER_THRESHHOLD = 939;
var scrollTo = function (offsetTop) {
var fixedHeaderOffset = HEADER_HEIGHT_SMALL;
if ($(window).width() > SMALL_HEADER_THRESHHOLD) {
fixedHeaderOffset = HEADER_HEIGHT_TALL;
}
$root.animate({
scrollTop: offsetTop - fixedHeaderOffset
}, ANIMATION_SPEED);
};
/**
* ## Collapsible Box
*
* Collapsible boxes act like 'accordions'. Clicking one will
* close all others and open it (or close it if it was already
* open).
*
* The implementation below works by changing the hash/anchor
* part of the document location (URL) to set the currently
* active box. This allows us to persist the changes during
* normal navigation and also, since the boxes are used to show
* 'steps' a user has to make, makes using the brower's back/
* forward buttons trivial.
*
* The event flow is like this:
*
* click --> location change --> re-evaluate box open states
*/
var COLLAPSIBLE_BOX = '.collapsible_box';
var COLLAPSIBLE_HEADER = '.collapsible_box-header';
var COLLAPSIBLE_CONTENT = '.collapsible_box-content';
function toggleBox($box, shouldOpen) {
if (!$box || !$box.length) { return; }
var openIt = !!shouldOpen;
$box
.find(COLLAPSIBLE_CONTENT)
.stop(true)
[openIt ? 'slideDown' : 'slideUp'](ANIMATION_SPEED)
.end()
.toggleClass("is-closed", !openIt).toggleClass("is-open", openIt);
}
function setVisibleBox($box) {
if (!$box || !$box.length) { return; }
// Box is open: Just close it.
if ($box.hasClass('is-open')) {
toggleBox($box, false);
return;
}
var $otherBoxes = $(COLLAPSIBLE_BOX).not($box);
// Close other boxes
toggleBox($otherBoxes, false);
// Open click on box
toggleBox($box, true);
}
function scrollToVisibleBox($box) {
setTimeout(function () {
scrollTo($box.offset().top);
}, ANIMATION_SPEED);
}
function setVisibleBoxFromLocation(callback) {
if (window.location.hash.indexOf('#!/') < 0) { return; }
var contentElementId = window.location.hash.slice(3);
var $box = $('#' + contentElementId).children(COLLAPSIBLE_BOX);
setVisibleBox($box);
if (typeof callback === 'function') {
callback($box);
}
}
$(window).on('hashchange', function (event) {
event.preventDefault();
setVisibleBoxFromLocation();
});
$(document).on('click', COLLAPSIBLE_HEADER, function (event) {
event.preventDefault();
var $contentElement = $(this).parents('.csc-default');
if (!$contentElement.length) { return; }
var hash = '#!/' + $contentElement.attr('id');
if (hash === window.location.hash) {
// No change, no hashchange event. We have to trigger it ourselves.
$(window).trigger('hashchange');
} else {
window.location.hash = hash;
}
});
// Initialize
setVisibleBoxFromLocation(function ($box) {
scrollToVisibleBox($box);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment