172 lines
4.2 KiB
JavaScript
172 lines
4.2 KiB
JavaScript
window.addEventListener('load', init);
|
|
|
|
let slides;
|
|
let currentSlide;
|
|
let topicList;
|
|
|
|
function init() {
|
|
slides = Array.from(document.querySelectorAll('article'));
|
|
for (let i = 0; i < slides.length; i++) {
|
|
slides[i].id = `slide${i}`;
|
|
}
|
|
resumeOrGoToStart();
|
|
topicList = createTopicList();
|
|
document.addEventListener('keydown', onKeyPressed);
|
|
}
|
|
|
|
function resumeOrGoToStart() {
|
|
let urlParts = window.location.href.split('#');
|
|
if (urlParts.length > 1) {
|
|
goToSlide(parseInt(urlParts[1].replace('slide', '')))
|
|
} else {
|
|
goToSlide(0)
|
|
}
|
|
}
|
|
|
|
function goToSlide(index) {
|
|
if (index >= 0 && index < slides.length) {
|
|
currentSlide = index;
|
|
window.location.href = window.location.href.split('#')[0] + `#slide${index}`;
|
|
}
|
|
}
|
|
|
|
function goToPreviousSlide() {
|
|
if (!showPreviousFragment()) {
|
|
goToSlide(currentSlide - 1);
|
|
}
|
|
}
|
|
|
|
function goToNextSlide() {
|
|
if (!showNextFragment()) {
|
|
goToSlide(currentSlide + 1);
|
|
}
|
|
}
|
|
|
|
function goToFirstSlide() {
|
|
goToSlide(0);
|
|
}
|
|
|
|
function goToLastSlide() {
|
|
goToSlide(slides.length - 1);
|
|
}
|
|
|
|
function onKeyPressed(event) {
|
|
switch (event.keyCode) {
|
|
case 34: // page down
|
|
case 40: // arrow down
|
|
case 39: // arrow right
|
|
goToNextSlide();
|
|
break;
|
|
case 33: // page up
|
|
case 38: // arrow up
|
|
case 37: // arrow left
|
|
goToPreviousSlide();
|
|
break;
|
|
case 36: // pos1
|
|
goToFirstSlide();
|
|
break;
|
|
case 35: // end
|
|
goToLastSlide();
|
|
break;
|
|
case 17: // ctrl
|
|
toggleTopicList();
|
|
break;
|
|
}
|
|
}
|
|
|
|
function showNextFragment() {
|
|
let fragments = [...slides[currentSlide].querySelectorAll('.fragment')]
|
|
let visible = [...slides[currentSlide].querySelectorAll('.fragment.visible')]
|
|
|
|
if (fragments.length == visible.length) {
|
|
return false;
|
|
} else {
|
|
fragments[visible.length].classList.add('visible')
|
|
return true;
|
|
}
|
|
}
|
|
|
|
function showPreviousFragment() {
|
|
let visible = [...slides[currentSlide].querySelectorAll('.fragment.visible')]
|
|
|
|
if (visible.length == 0) {
|
|
return false;
|
|
} else {
|
|
visible[visible.length - 1].classList.remove('visible')
|
|
return true;
|
|
}
|
|
}
|
|
|
|
function getTopicListContent() {
|
|
let results = [...document.querySelectorAll('h1, h2, h3, h4, h5, h6')];
|
|
let resultHtml = '<ul>';
|
|
let currentLevel = 1;
|
|
|
|
results.forEach(element => {
|
|
let node = element.nodeName;
|
|
let level = parseInt(node[node.length - 1]);
|
|
|
|
let parentElement = element.parentElement
|
|
while (parentElement.nodeName.toLowerCase() != 'article') {
|
|
parentElement = parentElement.parentElement;
|
|
}
|
|
let parentSlideID = parseInt(parentElement.id.replace('slide', ''));
|
|
|
|
if (level > currentLevel) {
|
|
resultHtml += `<ul><li><a href="javascript:goToSlide(${parentSlideID})">${element.textContent}</a></li>`;
|
|
currentLevel = level;
|
|
} else if (level < currentLevel) {
|
|
resultHtml += `</ul></li><li><a href="javascript:goToSlide(${parentSlideID})">${element.textContent}</a></li></li>`;
|
|
currentLevel = level;
|
|
} else {
|
|
resultHtml += `<li><a href="javascript:goToSlide(${parentSlideID})">${element.textContent}</a>`;
|
|
}
|
|
})
|
|
|
|
return resultHtml + '</ul>';
|
|
}
|
|
|
|
function createTopicList() {
|
|
let topicList = document.createElement(`div`);
|
|
topicList.innerHTML = getTopicListContent();
|
|
topicList.classList.add('topic-list')
|
|
document.body.appendChild(topicList);
|
|
topicList.style.position = 'fixed';
|
|
topicList.style.top = '4rem';
|
|
topicList.style.left = '50%';
|
|
topicList.style.transform = 'translateX(-50%)';
|
|
topicList.style.backgroundColor = 'white';
|
|
topicList.style.padding = '2rem';
|
|
topicList.style.width = '800px';
|
|
topicList.style.boxShadow = '0 5px 15px rgba(0, 0, 0, 0.3)';
|
|
topicList.style.maxHeight = 'calc(100vh - 8rem)';
|
|
topicList.style.boxSizing = 'border-box';
|
|
topicList.style.visibility = 'hidden';
|
|
topicList.style.overflowY = 'scroll';
|
|
|
|
topicList.querySelectorAll('a').forEach(link => {
|
|
link.addEventListener('click', e => topicList.style.visibility = 'hidden');
|
|
})
|
|
return topicList;
|
|
}
|
|
|
|
let lastCtrlPress = null;
|
|
|
|
function toggleTopicList() {
|
|
if (lastCtrlPress == null) {
|
|
lastCtrlPress = Date.now();
|
|
} else {
|
|
let now = Date.now();
|
|
if (now - lastCtrlPress < 400) {
|
|
lastCtrlPress = null;
|
|
if (topicList.style.visibility === 'visible') {
|
|
topicList.style.visibility = 'hidden';
|
|
} else {
|
|
topicList.style.visibility = 'visible';
|
|
}
|
|
} else {
|
|
lastCtrlPress = Date.now();
|
|
}
|
|
}
|
|
}
|