Tutorials

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()
    }
}