在下面,您将找到我为单击本地链接时平滑滚动创建的脚本。它是通过transform
完成的(没有 jQuery )。可以看到,我已经使用内联CSS 和外部样式表来实现了它。我建议使用内联版本,因为可能很难猜测相关样式表的索引。
但是,问题是滚动条的实际移动发生在应用转换之后。因此,如果在滚动过渡完成之前单击链接,则代码将无法正常工作。
对此有什么想法吗?
编辑:
我知道那里有jQuery solutions和third party polyfill libraries。但是,我的目标是用普通的JavaScript重新创建 jQuery 功能。
我的脚本:
// Get style rule's declaration block
function getStyleDeclaration(styleSheet, selectorText) {
const rules = styleSheet.cssRules;
return Array.from(rules).find(r => r.selectorText === selectorText).style;
// for (let i = 0; i < rules.length; i += 1) {
// if (rules[i].selectorText === selectorText) return rules[i].style;
// }
}
// Get specific style sheet, based on its title
// Many style sheets do not have a title however
// Which is main reason it is preferred to work with
// inline styles instead
function getStyleSheet(title) {
const styleSheets = document.styleSheets;
return Array.from(styleSheets).find(s => s.title === title);
// for (let i = 0; i < styleSheets.length; i += 1) {
// if (styleSheets[i].title === title) return styleSheets[i];
// }
}
function scrollToElement_ExternalStyleSheet(anchor, target) {
anchor.addEventListener("click", e => {
e.preventDefault();
const time = 1000;
// Distance from viewport to topof target
const distance = -target.getBoundingClientRect().top;
// Modify external style sheet
const transStyle = getStyleDeclaration(document.styleSheets[1], ".trans");
transStyle.transform = "translate(0, " + distance + "px)";
transStyle.transition = "transform " + time + "ms ease";
const root = document.documentElement; // <html> element
root.classList.add("trans");
window.setTimeout(() => {
root.classList.remove("trans");
root.scrollTo(0, -distance + window.pageYOffset);
}, time);
});
}
function scrollToElement_InlineStyle(anchor, target) {
const root = document.documentElement;
anchor.addEventListener('click', e => {
e.preventDefault();
const time = 900;
const distance = -target.getBoundingClientRect().top;
root.style.transform = 'translate(0, ' + distance + 'px)';
root.style.transition = 'transform ' + time + 'ms ease';
window.setTimeout(() => {
root.scrollTo(0, -distance + window.pageYOffset);
root.style.transform = null; // Revert to default
root.style.transition = null;
}, time);
});
}
function applySmoothScroll() {
const anchors = document.querySelectorAll("a");
const localAnchors = Array.from(anchors).filter(
a => a.getAttribute("href").indexOf("#") != -1
);
localAnchors.forEach(a => {
const targetString = a.getAttribute("href");
const target = document.querySelector(targetString);
// scrollToElement_ExternalStyleSheet(a, target);
scrollToElement_InlineStyle(a, target);
});
}
applySmoothScroll();
.box {
padding-bottom: 300px;
padding-top: 0.5rem;
background-color: orange;
text-align: center;
font-size: 200%;
}
.box:nth-child(even) {
background-color: lightblue;
color: white;
}
a {
color: black;
}
body {
margin: 0;
}
.trans {
transform: translate(0, -100px);
transition: transform 900ms ease;
}
<div id="s0" class="box"><a href="#s1">Click Me!</a></div>
<div id="s1" class="box"><a href="#s2">Click Me!</a></div>
<div id="s2" class="box"><a href="#s0">Click Me!</a></div>