Build mobile apps with simple HTML, CSS, and JS components. http://goratchet.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
4.3 KiB

!(function () {
'use strict';
// Ratchet's layout includes fixed position headers & footers that should always
// appear before the main .content div within <body>
//
// These fixed bars will have new content swapped in, ignoring any
// transitions (slide-in, slide-out & fade).
//
// These following selectors define which elements are transitioned with
// simple DOM replacement and are always immediate children of <body>
var barSelectors = [
'.bar-tab',
'.bar-nav',
'.bar-footer',
'.bar-header-secondary'
];
// Other than any fixed bars, '.content' should be the only other child of body
var contentSelector = '.content';
// For any bar elements in `newMarkup`, either:
// * replace an existing bar elements with new content
// * add new bar elements when an existing one isn't present
// * remove any bar elements not found in `newMarkup`
var updateBars = function (newMarkup) {
10 years ago
for (var i = 0; i < barSelectors.length; i++) {
var selector = barSelectors[i];
var newBar = newMarkup.querySelector(selector);
var existingBar = document.querySelector(selector);
if (newBar) {
displayBar(newBar, existingBar);
} else if (existingBar) {
existingBar.parentNode.removeChild(existingBar);
}
}
};
var displayBar = function (bar, container) {
if (container) {
container.innerHTML = '';
container.appendChild(bar);
} else {
// per Ratchet's CSS, bar elements must be the first thing in <body>
// here we assume `.content` is an immediate child of <body>
document.body.insertBefore(bar, document.querySelector(contentSelector));
}
};
var transitionContent = function (swap, container, transition, complete) {
var enter;
var containerDirection;
var swapDirection;
enter = /in$/.test(transition);
if (transition === 'fade') {
container.classList.add('in');
container.classList.add('fade');
swap.classList.add('fade');
}
if (/slide/.test(transition)) {
swap.classList.add('sliding-in', enter ? 'right' : 'left');
swap.classList.add('sliding');
container.classList.add('sliding');
}
container.parentNode.insertBefore(swap, container);
if (transition === 'fade') {
container.offsetWidth; // force reflow
container.classList.remove('in');
var fadeContainerEnd = function () {
container.removeEventListener(window.RATCHET.getTransitionEnd, fadeContainerEnd);
swap.classList.add('in');
swap.addEventListener(window.RATCHET.getTransitionEnd, fadeSwapEnd);
};
var fadeSwapEnd = function () {
swap.removeEventListener(window.RATCHET.getTransitionEnd, fadeSwapEnd);
container.parentNode.removeChild(container);
swap.classList.remove('fade');
swap.classList.remove('in');
complete && complete();
};
container.addEventListener(window.RATCHET.getTransitionEnd, fadeContainerEnd);
}
if (/slide/.test(transition)) {
var slideEnd = function () {
swap.removeEventListener(window.RATCHET.getTransitionEnd, slideEnd);
swap.classList.remove('sliding', 'sliding-in');
swap.classList.remove(swapDirection);
container.parentNode.removeChild(container);
complete && complete();
};
container.offsetWidth; // force reflow
swapDirection = enter ? 'right' : 'left';
containerDirection = enter ? 'left' : 'right';
container.classList.add(containerDirection);
swap.classList.remove(swapDirection);
swap.addEventListener('webkitTransitionEnd', slideEnd);
}
};
// `contents` must include an element with the class 'content' and can
// optionally include a number of Ratchet bar elements (see `barSelectors`)
var TRANSITION = function (contents, transition, complete) {
if (transition) {
updateBars(contents);
var existingContentDiv = document.querySelector(contentSelector);
var newContentDiv = contents.querySelector(contentSelector);
transitionContent(newContentDiv, existingContentDiv,
transition, complete);
} else {
document.body.innerHTML = '';
document.body.appendChild(contents);
complete && complete();
}
};
window.TRANSITION = TRANSITION;
}());