diff --git a/TODO.md b/TODO.md
index c9ae58b..653f537 100644
--- a/TODO.md
+++ b/TODO.md
@@ -15,7 +15,7 @@
- [x] add custom slug to all pages
- [x] test `postcss-easing-gradients` with Scss loaded in `/src`
- [ ] add md table of contents
-- [ ] new start page: https://labs.semplice.com/s5-vertical-grid
+- [x] new start page: https://labs.semplice.com/s5-vertical-grid
- [x] test purgecss with classes from Markdown files
- [ ] add NOW deployment
- [ ] Setup Nameserver
diff --git a/content/projects/__demo__/index.md b/content/projects/__demo__/index.md
index 03d43a1..7066df8 100644
--- a/content/projects/__demo__/index.md
+++ b/content/projects/__demo__/index.md
@@ -165,6 +165,17 @@ ModuleNotFoundError: No module named 'flask'
> cleaner yet i see a bird i stare at it i meow at it i do a wiggle come
> here, eat a plant, kill
+
+
+
+ Sleep in the bathroom sink allways wanting food. Rub whiskers on bare skin act innocent intently sniff hand intrigued by the shower.
+
+
+
+
+
## Images
![Caption could be here](img-01.jpg)
diff --git a/src/layouts/Article.jsx b/src/layouts/Article.jsx
index 73e0957..c82419c 100644
--- a/src/layouts/Article.jsx
+++ b/src/layouts/Article.jsx
@@ -1,6 +1,7 @@
import React from 'react'
import { scrollTo } from '../utils/animate'
+import { updateLocationHash, getDocumentHeight } from '../utils/helper'
import { prefersReducedMotion } from '../utils/accessibility'
import Lightbox from '../scripts/lightbox'
@@ -10,30 +11,64 @@ class Article extends React.Component {
componentDidMount() {
Lightbox.init()
- this.scrollElements = document.querySelectorAll(
- '.footnote-backref, .footnote-ref, .toc a'
- )
- this.scrollElements.forEach(ref => {
- ref.addEventListener('click', this.handleClick)
- })
+ // TODO: put article blocks into separate components
+ if (!prefersReducedMotion()) {
+ this.scrollElements = document.querySelectorAll(
+ '.footnote-backref, .footnote-ref, .toc a'
+ )
+ this.scrollElements.forEach((ref) => {
+ ref.addEventListener('click', this.handleClick)
+ })
+ }
}
componentWillUnmount() {
Lightbox.destroy()
- this.scrollElements.forEach(ref => {
- ref.removeEventListener('click', this.handleClick)
- })
+ if (this.scrollElements.length > 0) {
+ this.scrollElements.forEach((ref) => {
+ ref.removeEventListener('click', this.handleClick)
+ })
+ }
}
- handleClick(event) {
- if (prefersReducedMotion()) {
- return
- }
+ handleClick = (event) => {
event.preventDefault()
const target = document.getElementById(event.target.hash.substr(1))
if (target) {
- scrollTo(target)
+ const offsetPosition = scrollTo(target)
+
+ // highlight target element when reached
+ function onScrollEvent() {
+ if (
+ window.scrollY === offsetPosition || // reached element
+ window.scrollY === getDocumentHeight() - window.innerHeight || // reached document end
+ window.scrollY === 0 // reached document start
+ ) {
+ removeListeners()
+ updateLocationHash(target.id)
+
+ target.classList.add('highlight')
+ setTimeout(() => {
+ target.classList.remove('highlight')
+ }, 2400)
+ }
+ }
+
+ // remove event listeners when user interrupts `scrollTo` function
+ function detectScrollInterrupt() {
+ removeListeners()
+ }
+
+ function removeListeners() {
+ window.removeEventListener('scroll', onScrollEvent)
+ window.removeEventListener('wheel', detectScrollInterrupt)
+ window.removeEventListener('keyup', detectScrollInterrupt)
+ }
+
+ window.addEventListener('scroll', onScrollEvent)
+ window.addEventListener('wheel', detectScrollInterrupt)
+ window.addEventListener('keyup', detectScrollInterrupt)
}
}
@@ -48,7 +83,6 @@ class Article extends React.Component {
<>