mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-08-10 07:55:24 +02:00
small fixes
This commit is contained in:
parent
37fbf197ea
commit
d658954f26
4 changed files with 129 additions and 26 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
import { Decorators } from '../utils/decorators';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate dynamic table of content
|
* Generate dynamic table of content
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +87,7 @@ export default class TableOfContent {
|
||||||
calculateBoundings() {
|
calculateBoundings() {
|
||||||
this.tagsSectionsMap = this.tags.map((tag) => {
|
this.tagsSectionsMap = this.tags.map((tag) => {
|
||||||
const rect = tag.getBoundingClientRect();
|
const rect = tag.getBoundingClientRect();
|
||||||
const top = rect.top + window.scrollY;
|
const top = Math.floor(rect.top + window.scrollY);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
top,
|
top,
|
||||||
|
@ -103,7 +105,11 @@ export default class TableOfContent {
|
||||||
* Find the nearest section above the scroll position
|
* Find the nearest section above the scroll position
|
||||||
*/
|
*/
|
||||||
const section = this.tagsSectionsMap.filter((tag) => {
|
const section = this.tagsSectionsMap.filter((tag) => {
|
||||||
return tag.top < scrollPosition;
|
console.log('scrollPosition', scrollPosition);
|
||||||
|
console.log('tag', tag);
|
||||||
|
console.log('tag.top <= scrollPosition', tag.top <= scrollPosition);
|
||||||
|
|
||||||
|
return tag.top <= scrollPosition;
|
||||||
}).pop();
|
}).pop();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,7 +130,9 @@ export default class TableOfContent {
|
||||||
/**
|
/**
|
||||||
* Define a flag to reduce number of calls to detectSection function
|
* Define a flag to reduce number of calls to detectSection function
|
||||||
*/
|
*/
|
||||||
let ticking;
|
const delayedDetectSectionFunction = Decorators.debounce((lastKnownScrollPosition) => {
|
||||||
|
detectSection(lastKnownScrollPosition);
|
||||||
|
}, 200);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll listener
|
* Scroll listener
|
||||||
|
@ -133,33 +141,25 @@ export default class TableOfContent {
|
||||||
/**
|
/**
|
||||||
* Calculate scroll position
|
* Calculate scroll position
|
||||||
*/
|
*/
|
||||||
let lastKnownScrollPosition = 1 + window.scrollY;
|
let lastKnownScrollPosition = this.getScrollPadding() + window.scrollY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If fixed header is present then calculate scroll position based on it
|
* If fixed header is present then calculate scroll position based on it
|
||||||
*/
|
*/
|
||||||
if (this.fixedHeaderSelector) {
|
// if (this.fixedHeaderSelector) {
|
||||||
const fixedHeader = document.querySelector(this.fixedHeaderSelector);
|
// const fixedHeader = document.querySelector(this.fixedHeaderSelector);
|
||||||
|
//
|
||||||
if (fixedHeader) {
|
// if (fixedHeader) {
|
||||||
lastKnownScrollPosition += fixedHeader.getBoundingClientRect().height;
|
// lastKnownScrollPosition += fixedHeader.getBoundingClientRect().height;
|
||||||
} else {
|
// } else {
|
||||||
console.warn(`Fixed header was not found by selector ${this.fixedHeaderSelector}`);
|
// console.warn(`Fixed header was not found by selector ${this.fixedHeaderSelector}`);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call section detecting function
|
* Call section detecting function
|
||||||
*/
|
*/
|
||||||
if (!ticking) {
|
delayedDetectSectionFunction(lastKnownScrollPosition);
|
||||||
window.requestAnimationFrame(() => {
|
|
||||||
detectSection(lastKnownScrollPosition);
|
|
||||||
|
|
||||||
ticking = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
ticking = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ export default class TableOfContent {
|
||||||
/**
|
/**
|
||||||
* Show the top of table of content
|
* Show the top of table of content
|
||||||
*/
|
*/
|
||||||
document.querySelector(`.${this.CSS.tocHeader}`).scrollIntoViewIfNeeded();
|
document.querySelector(`.${this.CSS.tocHeader}`).scrollIntoViewIfNeeded();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -286,4 +286,46 @@ export default class TableOfContent {
|
||||||
listItem.scrollIntoViewIfNeeded();
|
listItem.scrollIntoViewIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get scroll padding top value from HTML element
|
||||||
|
*
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
getScrollPadding() {
|
||||||
|
const defaultScrollPaddingValue = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to get calculated value or fallback to default value
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
/**
|
||||||
|
* Getting the HTML element
|
||||||
|
*/
|
||||||
|
const htmlElement = document.getElementsByTagName('html')[0];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If element is not found then return 0
|
||||||
|
*/
|
||||||
|
if (!htmlElement) {
|
||||||
|
return defaultScrollPaddingValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getting css scroll padding value
|
||||||
|
*/
|
||||||
|
const scrollPaddingTopValue = getComputedStyle(htmlElement)
|
||||||
|
.getPropertyValue('scroll-padding-top');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse value to number
|
||||||
|
*/
|
||||||
|
return parseInt(scrollPaddingTopValue, 10);
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On any errors return default value
|
||||||
|
*/
|
||||||
|
return defaultScrollPaddingValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
62
src/frontend/js/utils/decorators.js
Normal file
62
src/frontend/js/utils/decorators.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* A few useful utility functions
|
||||||
|
*/
|
||||||
|
export class Decorators {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param func
|
||||||
|
* @param ms
|
||||||
|
* @return {wrapper}
|
||||||
|
*/
|
||||||
|
static throttle(func, ms) {
|
||||||
|
let isThrottled = false,
|
||||||
|
savedArgs,
|
||||||
|
savedThis;
|
||||||
|
|
||||||
|
function wrapper() {
|
||||||
|
if (isThrottled) { // (2)
|
||||||
|
savedArgs = arguments;
|
||||||
|
savedThis = this;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func.apply(this, arguments); // (1)
|
||||||
|
|
||||||
|
isThrottled = true;
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
isThrottled = false; // (3)
|
||||||
|
|
||||||
|
if (savedArgs) {
|
||||||
|
wrapper.apply(savedThis, savedArgs);
|
||||||
|
savedArgs = savedThis = null;
|
||||||
|
}
|
||||||
|
}, ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debounce decorator function
|
||||||
|
*
|
||||||
|
* @param {Function} f - function to debounce
|
||||||
|
* @param {number} ms - milliseconds to debounce
|
||||||
|
*
|
||||||
|
* @returns {(function(): void)|*}
|
||||||
|
*/
|
||||||
|
static debounce(f, ms) {
|
||||||
|
let isCooldown = false;
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
if (isCooldown) return;
|
||||||
|
|
||||||
|
f.apply(this, arguments);
|
||||||
|
|
||||||
|
isCooldown = true;
|
||||||
|
|
||||||
|
setTimeout(() => isCooldown = false, ms);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to handle interaction with local storage
|
* Utility class to handle interaction with local storage
|
||||||
*/
|
*/
|
||||||
|
@ -27,4 +26,4 @@ export class Storage {
|
||||||
get() {
|
get() {
|
||||||
return localStorage.getItem(this.key);
|
return localStorage.getItem(this.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
html {
|
html {
|
||||||
scroll-padding-top: var(--layout-height-header);
|
scroll-padding-top: calc(var(--layout-height-header) + 5vh);
|
||||||
}
|
}
|
||||||
|
|
||||||
.docs-header {
|
.docs-header {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue