Dynamically set URL and title
Updating the browser URL as the visitor scrolls over articles in a multi article scroll flow is highly implementation dependent. The solution used here may not work for your site, but it gives an idea of how it can be done.
Structure
<div data-pathname="/editorial-article-1" data-title="Editorial article 1">
Editorial article 1
</div>
<div data-adk-container="native-scroll"></div>
<div data-pathname="/editorial-article-2" data-title="Editorial article 2">
Editorial article 2
</div>
Scroll handling
/*
* Traverses the element hierarchy to the top, starting with given element,
* returning the first element that has a pathname data attribute.
*/
const findDataElement = (elem) => {
if (elem) {
const pathname = elem.dataset && elem.dataset.pathname
return pathname ? elem : findDataElement(elem.parentNode)
}
}
/*
* The scroll handler gets the element in the middle of the viewport,
* finds the data element and sets the URL and title accordingly.
*/
const handleScroll = () => {
const { innerWidth, innerHeight } = window
const elem = findDataElement(document.elementFromPoint(innerWidth / 2, innerHeight / 2))
if (elem) {
const { pathname, title } = elem.dataset
document.title = title
window.history.replaceState({}, title, pathname)
}
}
/*
* Attach a scroll event listener. The handler function should be throttled
* to avoid performance issues. There are libraries and utilities for doing
* throttling, but if you want a vanilla JS implementation you will find one
* at the bottom of this page.
*/
window.addEventListener('scroll', throttle(handleScroll, 100), true)
Setup
adk.config()
.addContainer('native-scroll', adk.container.config()
.provider('adk.placement')
.params({
adapters: {
'com.advisible.native.article': {
afterLoad: ({ err, item, containerId }) => {
if (!err) {
const [name, instance] = containerId.split('_')
const containerElem = adk.container.getElement(name, instance)
containerElem.dataset.pathname = new URL(item.url).pathname
containerElem.dataset.title = item.headline
}
},
},
},
}))
.apply()
.init(publisherId)
Result
Editorial article 1
Editorial article 2
throttle.js
const throttle = (fn, delay) => {
if (delay === 0) {
return fn
}
let lastCall = 0
return () => {
const now = Date.now()
if (now - lastCall < delay) {
return
}
lastCall = now
return fn()
}
}