ArticleTemplates/assets/js/modules/immersive.js (127 lines of code) (raw):
import { getElementOffset, debounce } from 'modules/util';
function addDropCapToNextElementSibling(element) {
const nextParagraphSibling = element.nextElementSibling;
if (nextParagraphSibling &&
nextParagraphSibling.tagName === 'P' &&
nextParagraphSibling.firstChild &&
nextParagraphSibling.firstChild.tagName !== 'STRONG') {
nextParagraphSibling.classList.add('has__dropcap');
}
}
function addClassesToSectionSeparators() {
let i;
let header;
const headers = document.querySelectorAll('.article h2');
for (i = 0; i < headers.length; i++) {
header = headers[i];
if (header.innerText.trim() === '* * *' || header.classList.contains('section__rule')) {
header.innerHTML = '';
header.classList.add('section__rule');
addDropCapToNextElementSibling(header);
}
}
}
function addClassesToElementImmersives() {
let i;
let elementImmersive;
const elementImmersives = document.querySelectorAll('figure.element--immersive');
let nextSibling;
for (i = 0; i < elementImmersives.length; i++) {
elementImmersive = elementImmersives[i];
nextSibling = elementImmersive.nextElementSibling;
if (nextSibling &&
nextSibling.classList.contains('element-pullquote')) {
nextSibling.classList.add('quote--image');
elementImmersive.classList.add('quote--overlay');
elementImmersive.dataset.thing = '';
}
if (nextSibling &&
nextSibling.tagName === 'H2' &&
!nextSibling.classList.contains('section__rule')) {
elementImmersive.classList.add('title--overlay');
nextSibling.classList.add('title--image');
addDropCapToNextElementSibling(nextSibling);
}
}
}
function movePullQuotes() {
let i;
let pullQuote;
const pullQuotes = document.getElementsByClassName('element-pullquote');
for (i = 0; i < pullQuotes.length; i++) {
pullQuote = pullQuotes[i];
pullQuote.dataset.offset = getElementOffset(pullQuote).top;
}
}
function onQuoteOverlayClick(quoteOverlay, evt) {
let figcaption;
evt.preventDefault();
figcaption = quoteOverlay.getElementsByTagName('figcaption')[0];
if (figcaption) {
if (figcaption.classList.contains('display')) {
figcaption.classList.remove('display');
} else {
figcaption.classList.add('display');
}
}
}
function onImmersiveScroll() {
let i;
let dataOffset;
let pullQuote;
const pullQuotes = document.getElementsByClassName('element-pullquote');
const viewPortHeight = document.documentElement.clientHeight;
const pageOffset = viewPortHeight * 0.75;
for (i = 0; i < pullQuotes.length; i++) {
pullQuote = pullQuotes[i];
dataOffset = pullQuote.dataset.offset;
if (window.scrollY >= (dataOffset - pageOffset)) {
pullQuote.classList.add('animated');
pullQuote.classList.add('fadeInUp');
}
}
}
function getImageHeight() {
const viewPortHeight = document.documentElement.clientHeight * 0.9;
const marginTop = document.body.style.marginTop.replace('px', '');
return viewPortHeight - marginTop;
}
function adjustHeaderImageHeight() {
let embed;
const headerContainer = document.querySelector('.article__header-bg, .article__header-bg .element > iframe');
if (headerContainer) {
embed = headerContainer.getElementsByClassName('element-embed')[0] || headerContainer.getElementsByClassName('element-atom')[0];
if (embed || headerContainer.dataset.fullScreen) {
headerContainer.style.height = `${getImageHeight()}px`;
if (embed) {
embed.classList.add('height-adjusted');
}
}
}
}
function attachImmersiveEventHandlers() {
let i;
let quoteOverlay;
const quoteOverlays = document.getElementsByClassName('quote--overlay');
for (i = 0; i < quoteOverlays.length; i++) {
quoteOverlay = quoteOverlays[i];
quoteOverlay.addEventListener('click', onQuoteOverlayClick.bind(null, quoteOverlay));
}
window.addEventListener('scroll', debounce(onImmersiveScroll, 10));
if (GU.opts.platform !== 'ios') {
window.addEventListener('resize', debounce(adjustHeaderImageHeight, 100));
}
}
function formatImmersive() {
if (GU.opts.platform !== 'ios') {
adjustHeaderImageHeight();
}
// find all the section seperators & add classes
addClassesToSectionSeparators();
// for each element--immersive add extra classes depending on siblings
addClassesToElementImmersives();
// store all pullquotes top offset for later
movePullQuotes();
// attach event handlers
attachImmersiveEventHandlers();
}
function init() {
formatImmersive();
}
export { init };