没有 jQuery 的平滑滚动锚链接

是否有可能使用平滑滚动锚链接,但 没有 jQuery?我正在创建一个新的网站,我不想使用 jQuery

119745 次浏览

使用从这里开始的函数: JavaScript 动画并修改它来修改一个属性(不仅仅是样式的属性) ,您可以尝试这样做:

演示: < a href = “ http://jsfiddle.net/7TAa2/1/”rel = “ nofollow noReferrer”> http://jsfiddle.net/7taa2/1/

我只是说..。

function animate(elem, style, unit, from, to, time, prop) {
if (!elem) {
return;
}
var start = new Date().getTime(),
timer = setInterval(function() {
var step = Math.min(1, (new Date().getTime() - start) / time);
if (prop) {
elem[style] = (from + step * (to - from)) + unit;
} else {
elem.style[style] = (from + step * (to - from)) + unit;
}
if (step === 1) {
clearInterval(timer);
}
}, 25);
if (prop) {
elem[style] = from + unit;
} else {
elem.style[style] = from + unit;
}
}


window.onload = function() {
var target = document.getElementById("div5");
animate(document.scrollingElement || document.documentElement, "scrollTop", "", 0, target.offsetTop, 2000, true);
};
div {
height: 50px;
}
<div id="div1">asdf1</div>
<div id="div2">asdf2</div>
<div id="div3">asdf3</div>
<div id="div4">asdf4</div>
<div id="div5">asdf5</div>
<div id="div6">asdf6</div>
<div id="div7">asdf7</div>
<div id="div8">asdf8</div>
<div id="div9">asdf9</div>
<div id="div10">asdf10</div>
<div id="div10">asdf11</div>
<div id="div10">asdf12</div>
<div id="div10">asdf13</div>
<div id="div10">asdf14</div>
<div id="div10">asdf15</div>
<div id="div10">asdf16</div>
<div id="div10">asdf17</div>
<div id="div10">asdf18</div>
<div id="div10">asdf19</div>
<div id="div10">asdf20</div>

带有 :target选择器的 CSS3转换可以给出一个不错的结果,而不需要任何 JS 修改。我只是在考虑是否要实现它,但是没有 Jquery,它确实会有点乱。详情请参阅 这个问题

扩展这个答案: https://stackoverflow.com/a/8918062/3851798

定义 scrollTo 函数后,可以在函数中传递要 scrollTo 的元素。

function scrollTo(element, to, duration) {
if (duration <= 0) return;
var difference = to - element.scrollTop;
var perTick = difference / duration * 10;


setTimeout(function() {
element.scrollTop = element.scrollTop + perTick;
if (element.scrollTop === to) return;
scrollTo(element, to, duration - 10);
}, 10);
}

如果有一个 id = “ footer”的 div

<div id="footer" class="categories">…</div>

在运行滚动的脚本中,可以运行以下命令,

elmnt = document.getElementById("footer");
scrollTo(document.body, elmnt.offsetTop, 600);

就是这样。不使用 jQuery 的平滑滚动。实际上,您可以在浏览器的控制台上使用这些代码,并根据自己的喜好对其进行微调。

实际上,有一种更轻量级、更简单的方法可以做到这一点: Https://codepen.io/ugg0t/pen/mqbbby

function scrollTo(element) {
window.scroll({
behavior: 'smooth',
left: 0,
top: element.offsetTop
});
}


document.getElementById("button").addEventListener('click', () => {
scrollTo(document.getElementById("8"));
});
div {
width: 100%;
height: 200px;
background-color: black;
}


div:nth-child(odd) {
background-color: white;
}


button {
position: absolute;
left: 10px;
top: 10px;
}
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
<div id="5"></div>
<div id="6"></div>
<div id="7"></div>
<div id="8"></div>
<div id="9"></div>
<div id="10"></div>
<button id="button">Button</button>

用这个:

let element = document.getElementById("box");


element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({block: "end"});
element.scrollIntoView({behavior: "instant", block: "end", inline: "nearest"});

Https://jsfiddle.net/anderpo/x8ucc5ak/1/

我最喜欢的滚动到库目前是 禅卷,因为它的 各种各样的特征和小尺寸(目前只有3.17 kb)。

将来使用原生的 scrollIntoView功能可能会更有意义,但是由于现在大多数生产站点由于缺乏 IE 支持而不得不使用多边形填充,所以我建议在所有情况下都使用 Zenroll。

填充材料的光滑滚动性能..。

例如:

document.querySelectorAll('a[href^="#"]').addEventListener("click", function(event) {
event.preventDefault();
document.querySelector(this.getAttribute("href")).scrollIntoView({ behavior: "smooth" });
});

储存库: https://github.com/iamdustan/smoothscroll

这是@Ian 的升级版

// Animated scroll with pure JS
// duration constant in ms
const animationDuration = 600;
// scrollable layout
const layout = document.querySelector('main');
const fps = 12;  // in ms per scroll step, less value - smoother animation
function scrollAnimate(elem, style, unit, from, to, time, prop) {
if (!elem) {
return;
}
var start = new Date().getTime(),
timer = setInterval(function () {
var step = Math.min(1, (new Date().getTime() - start) / time);
var value =  (from + step * (to - from)) + unit;
if (prop) {
elem[style] = value;
} else {
elem.style[style] = value;
}
if (step === 1) {
clearInterval(timer);
}
}, fps);
if (prop) {
elem[style] = from + unit;
} else {
elem.style[style] = from + unit;
}
}


function scrollTo(hash) {
const target = document.getElementById(hash);
const from = window.location.hash.substring(1) || 'start';
const offsetFrom = document.getElementById(from).offsetTop;
const offsetTo = target.offsetTop;
scrollAnimate(layout,
"scrollTop", "", offsetFrom, offsetTo, animationDuration, true);
setTimeout(function () {
window.location.hash = hash;
}, animationDuration+25)
};


// add scroll when click on menu items
var menu_items = document.querySelectorAll('a.mdl-navigation__link');
menu_items.forEach(function (elem) {
elem.addEventListener("click",
function (e) {
e.preventDefault();
scrollTo(elem.getAttribute('href').substring(1));
});
});


// scroll when open link with anchor
window.onload = function () {
if (window.location.hash) {
var target = document.getElementById(window.location.hash.substring(1));
scrollAnimate(layout, "scrollTop", "", 0, target.offsetTop, animationDuration, true);
}
}

下面是 纯 JavaScript中的一个简单解决方案,它利用了 CSS 属性 滚动行为: 平滑

function scroll_to(id) {
document.documentElement.style.scrollBehavior = 'smooth'
element = document.createElement('a');
element.setAttribute('href', id)
element.click();
}

用法 :

假设我们有10个 div:

<div id='df7ds89' class='my_div'>ONE</div>
<div id='sdofo8f' class='my_div'>TWO</div>
<div id='34kj434' class='my_div'>THREE</div>
<div id='gbgfh98' class='my_div'>FOUR</div>
<div id='df89sdd' class='my_div'>FIVE</div>
<div id='34l3j3r' class='my_div'>SIX</div>
<div id='56j5453' class='my_div'>SEVEN</div>
<div id='75j6h4r' class='my_div'>EIGHT</div>
<div id='657kh54' class='my_div'>NINE</div>
<div id='43kjhjh' class='my_div'>TEN</div>

我们可以:

scroll_to('#657kh54')

你只需要 在单击事件中调用此函数(例如点击按钮然后滚动到 div # 9)。

结果 :

enter image description here

当然,在现实生活中看起来要平滑得多。

小提琴

不幸的是,IE 和 Safari 在 二零一九年中不支持 scrollBehavior = ‘川流不息’

enter image description here MDN 网络文档

Vanilla js 变体,使用 requestAnimationFrame,支持所有浏览器:

const requestAnimationFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame;


function scrollTo(to) {
const start = window.scrollY || window.pageYOffset
const time = Date.now()
const duration = Math.abs(start - to) / 3;


(function step() {
var dx = Math.min(1, (Date.now() - time) / duration)
var pos = start + (to - start) * easeOutQuart(dx)


window.scrollTo(0, pos)


if (dx < 1) {
requestAnimationFrame(step)
}
})()
}

支持任何 放松

试试这里的代码:

window.scrollTo({
top: 0,
left: 0,
behavior: 'smooth'
});

对于2019年的任何人来说, 首先,添加一个事件侦听器

  document.getElementById('id').addEventListener('click', () => scrollTo())

然后你瞄准元素,顺利地到达它

function scrollTo() {
let target = document.getElementById('target');
target.scrollIntoView({
behavior: "smooth",
block: "end",
inline: "nearest"
})
}

这是一个相当老的问题,但是重要的是现在 CSS 支持平滑滚动,所以不需要任何脚本:

html {
scroll-behavior: smooth;
}

正如 @ Andiih指出的那样,截至2022年底,这方面的 完全支持浏览器已经存在。

基于 MDN 文件的滚动选项,我们可以使用以下代码:

element.scrollTo({
top: 100,
left: 100,
behavior: 'smooth'
});

事实上,behavior键可以接受 smoothauto变量。第一个是平稳运动,第二个是单跳。

有关平滑滚动的更全面的方法列表,请参见我的答案 给你


为了在一定的时间内滚动到一定的位置,可以使用 window.requestAnimationFrame,每次计算适当的电流位置。当不支持 requestAnimationFrame时,可以使用 setTimeout达到类似的效果。

/*
@param pos: the y-position to scroll to (in pixels)
@param time: the exact amount of time the scrolling will take (in milliseconds)
*/
function scrollToSmoothly(pos, time) {
var currentPos = window.pageYOffset;
var start = null;
if(time == null) time = 500;
pos = +pos, time = +time;
window.requestAnimationFrame(function step(currentTime) {
start = !start ? currentTime : start;
var progress = currentTime - start;
if (currentPos < pos) {
window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
} else {
window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
}
if (progress < time) {
window.requestAnimationFrame(step);
} else {
window.scrollTo(0, pos);
}
});
}

演示:

function scrollToSmoothly(pos, time) {
var currentPos = window.pageYOffset;
var start = null;
if(time == null) time = 500;
pos = +pos, time = +time;
window.requestAnimationFrame(function step(currentTime) {
start = !start ? currentTime : start;
var progress = currentTime - start;
if (currentPos < pos) {
window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
} else {
window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
}
if (progress < time) {
window.requestAnimationFrame(step);
} else {
window.scrollTo(0, pos);
}
});
}


document.getElementById("toElement").addEventListener('click', function(e) {
var elem = document.querySelector("div");
scrollToSmoothly(elem.offsetTop);
});
document.getElementById("toTop").addEventListener('click', function(e){
scrollToSmoothly(0, 700);
});
<button id="toElement">Scroll To Element</button>
<div style="margin: 1000px 0px; text-align: center;">Div element
<button id="toTop">Scroll back to top</button>
</div>

对于更复杂的情况,可以使用 SmoothScroll.js 库,它可以处理垂直和水平的平滑滚动、在其他容器元素内部滚动、不同的放松行为、从当前位置相对滚动等等。

document.getElementById("toElement").addEventListener('click', function(e) {
smoothScroll({toElement: document.querySelector('div'), duration: 500});
});
document.getElementById("toTop").addEventListener('click', function(e){
smoothScroll({yPos: 0, duration: 700});
});
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/SmoothScroll@1.2.0/src/smoothscroll.min.js" integrity="sha384-UdJHYJK9eDBy7vML0TvJGlCpvrJhCuOPGTc7tHbA+jHEgCgjWpPbmMvmd/2bzdXU" crossorigin="anonymous"></script>
<button id="toElement">Scroll To Element</button>
<div style="margin: 1000px 0px; text-align: center;">Div element
<button id="toTop">Scroll back to top</button>
</div>

或者,您可以将选项对象传递给 window.scroll,它可以滚动到特定的 x 和 y 位置,而 window.scrollBy可以从当前位置滚动一定量:

// Scroll to specific values
// scrollTo is the same
window.scroll({
top: 2500,
left: 0,
behavior: 'smooth'
});


// Scroll certain amounts from current position
window.scrollBy({
top: 100, // could be negative value
left: 0,
behavior: 'smooth'
});

演示:

<button onClick="scrollToDiv()">Scroll To Element</button>
<div style="margin: 500px 0px;">Div</div>
<script>
function scrollToDiv(){
var elem = document.querySelector("div");
window.scroll({
top: elem.offsetTop,
left: 0,
behavior: 'smooth'
});
}
</script>

现代浏览器支持 属性,它可以使文档中的滚动变得平滑(不需要 JavaScript)。锚标记可以通过给锚标记一个 href#加上要滚动到的元素的 id来实现)。您还可以为特定容器(如 div)设置 scroll-behavior属性,以使其内容顺利滚动。

html, body{
scroll-behavior: smooth;
}
<a href="#elem">Scroll To Element</a>
<div id="elem" style="margin: 500px 0px;">Div</div>

没有 JQuery

const links = document.querySelectorAll('header nav ul a')


for (const link of links) {
link.onclick = function clickHandler(e) {
e.preventDefault()
const href = this.getAttribute('href')
document.querySelector(href).scrollIntoView({ behavior: 'smooth' })
}
}
  body {
background-color: black;
height:7000px
}


header {
margin-top: 1.3rem;
margin-bottom: 25rem;
display: flex;
justify-content: center;
align-items: center;
}


nav ul {
display: flex;
}


nav ul li {
all: unset;
margin: 2rem;
cursor: pointer;
}


nav ul li a {
all: unset;
font: bold 1.8rem robto;
color: white;
letter-spacing: 1px;
cursor: pointer;
padding-top: 3rem;
padding-bottom: 2rem;
}


#team,
#contact,
#about {
background-color: #e2df0d;
width: 100%;
height: 35rem;
display: flex;
justify-content: center;
align-items: center;
color: black;
font: bold 4rem roboto;
letter-spacing: 6.2px;
margin-top: 70rem;


}
<header>
<!-- NavBar -->
<nav>
<ul>
<li><a href="#team">Team</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#about">About</a></li>
</ul>
</nav>
</header>


<!-- ----------- Team ----------------------- -->
<div id="team">
<h2>Team</h2>
</div>


<!-- ----------- Contact ----------------------- -->
<div id="contact">
<h2>Contact</h2>
</div>


<!-- ----------- About ----------------------- -->
<div id="about">
<h2>About</h2>
</div>

或者只支持 CSS,但是还不是所有的浏览器都支持它

html {scroll-behavior: smooth}

如果你想设置你所有的深层链接 #顺利滚动,你可以这样做:

const allLinks = document.querySelectorAll('a[href^="#"]')
allLinks.forEach(link => {


const
targetSelector = link.getAttribute('href'),
target = document.querySelector(targetSelector)


if (target) {
link.addEventListener('click', function(e) {


e.preventDefault()


const top = target.offsetTop // consider decreasing your main nav's height from this number


window.scroll({
behavior: 'smooth',
left: 0,
top: top
});


})
}
})

一个示例代码,也考虑你的主导航的高度(这个代码去哪里 top常量声明) :

const
mainHeader = document.querySelector('header#masthead'), //change to your correct main nav selector
mainHeaderHeight = mainHeader.offsetHeight,
// now calculate top like this:
top = target.offsetTop - mainHeaderHeight

二零二二年三月

我知道这是一个古老的问题,但想提出一个答案,有更简单的方法在现代做到这一点。到目前为止,几乎所有的主流浏览器都与 scroll-behavior兼容,包括最新版本的 Safari。不过,您可能希望使用备份方法,或者仅仅使用方法2中描述的 javascript 方法来兼容旧的浏览器。

方法1: HTML 和 CSS

你可以这样做

<a href="#target" id="scroll-trigger">Click</a>
.
.
.
<h2 id="target">Target</h2>

和 CSS

html {
scroll-behavior: smooth
}

方法2: JavaScript

或者,如果您有一个需要 javascript 的独特案例,请继续详细说明这个方法。

const scrollTrigger = document.getElementById('scroll-trigger');
const target = document.getElementById('target');


scrollTrigger.addEventListener('click', function (e) {
window.scroll({
top: target.offsetTop,
left:0,
behavior: 'smooth' });
}, false)

这里是最优雅和简洁的解决方案。

相关网址:

<a href="#elementIDtoScrollTo"></a>

CSS:

html {
scroll-behavior: smooth;
}

记住向每个 HTML 元素添加唯一的 id="elementIDtoScrollTo"