You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
1.9 KiB
79 lines
1.9 KiB
function getElementPosition(el) { |
|
const docEl = document.documentElement; |
|
const docRect = docEl.getBoundingClientRect(); |
|
const elRect = el.getBoundingClientRect(); |
|
return { |
|
x: elRect.left - docRect.left, |
|
y: elRect.top - docRect.top |
|
}; |
|
} |
|
|
|
function getElement(to) { |
|
const targetAnchor = to.hash.slice(1); |
|
return document.getElementById(targetAnchor) || document.querySelector(`[name='${targetAnchor}']`); |
|
} |
|
|
|
function scrollToAnchor(to) { |
|
const targetElement = getElement(to); |
|
|
|
if (targetElement) { |
|
return window.scrollTo({ |
|
top: getElementPosition(targetElement).y, |
|
behavior: 'smooth' |
|
}); |
|
} |
|
} |
|
|
|
export default ({ |
|
Vue, |
|
options, |
|
router, |
|
siteData, |
|
isServer |
|
}) => { |
|
// Workaround of vuepress #1499 |
|
router.options.scrollBehavior = (to, from, savedPosition) => { |
|
if (savedPosition) { |
|
return window.scrollTo({ |
|
top: savedPosition.y, |
|
behavior: 'smooth' |
|
}); |
|
} else if (to.hash) { |
|
if (Vue.$vuepress.$get('disableScrollBehavior')) { |
|
return false; |
|
} |
|
new Promise((resolve, reject) => { |
|
if (getElement(to)) { |
|
resolve(); |
|
} else { |
|
const timeout = Date.now() + 10000; |
|
const timer = window.setInterval(() => { |
|
if (getElement(to)) { |
|
resolve(); |
|
window.clearInterval(timeout); |
|
} else if (Date.now() > timeout) { |
|
reject(); |
|
} |
|
}, 100); |
|
} |
|
}).then(() => { |
|
const promises = []; |
|
document.querySelectorAll('img').forEach(image => { |
|
if (!image.complete) { |
|
promises.push(new Promise(resolve => { |
|
image.onload = resolve; |
|
})); |
|
} |
|
}); |
|
Promise.all(promises).then(() => { |
|
scrollToAnchor(to); |
|
}); |
|
}); |
|
} else { |
|
return window.scrollTo({ |
|
top: 0, |
|
behavior: 'smooth' |
|
}); |
|
} |
|
}; |
|
}
|
|
|