平滑滚动锚链接没有jQuery

dro*_*ski 51 javascript anchor hyperlink

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

Tej*_*hah 51

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

定义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);
}
Run Code Online (Sandbox Code Playgroud)

如果你有一个id ="footer"的div

<div id="footer" class="categories">…</div>
Run Code Online (Sandbox Code Playgroud)

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

elmnt = document.getElementById("footer");
scrollTo(document.body, elmnt.offsetTop, 600);
Run Code Online (Sandbox Code Playgroud)

你有它.没有jQuery的平滑滚动.您可以在浏览器的控制台上实际使用该代码并根据自己的喜好进行微调.

  • 我必须将`document.documentElement`传递给函数而不是`document.body`才能使它工作 (8认同)

Ian*_*Ian 42

使用此处的函数:JavaScript动画并修改它以修改属性(不仅仅是样式的属性),您可以尝试这样的事情:

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);
};
Run Code Online (Sandbox Code Playgroud)

演示: https ://jsfiddle.net/zpu16nen/

确保你的窗口尺寸足够小,所以实际上有一个滚动条,可以滚动到第5个div.

不,它不需要重新创建25%的jQuery.

这显然需要高度修改,具体取决于你的问题实际意味着什么(比如当窗口哈希发生变化时,或类似的东西).

请注意,使用jQuery,它很简单:

$(document).ready(function () {
    $("html, body").animate({
        scrollTop: $("#div5").offset().top
    }, 2000);
});
Run Code Online (Sandbox Code Playgroud)

演示: http ://jsfiddle.net/7TAa2/1/

只是说......

  • 对于尝试这样做的人:这是一个很好的剧本,但不要指望任何缓和或好的补间.这是一种原始的steppy动画. (2认同)

Ale*_*tly 28

实际上,有更轻量级和简单的方法: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"));
});
Run Code Online (Sandbox Code Playgroud)
div {
  width: 100%;
  height: 200px;
  background-color: black;
}

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

button {
  position: absolute;
  left: 10px;
  top: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 唯一的问题是,而不是``element.offsetTop``你应该使用``element.getBoundingClientRect().top + window.scrollY`` (3认同)
  • 请记住,它在IE和Edge上不起作用 (2认同)

Ale*_*iré 14

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

html {
  scroll-behavior: smooth;
}
Run Code Online (Sandbox Code Playgroud)

正如@Andiih所指出的,截至 2022 年末,浏览器对此已提供全面支持。


小智 7

Vanilla js 变体使用requestAnimationFrameeasings 并支持所有浏览器:

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)
        }
    })()
}
Run Code Online (Sandbox Code Playgroud)

支持任何宽松


And*_*rpo 5

用这个:

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

element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({block: "end"});
element.scrollIntoView({behavior: "instant", block: "end", inline: "nearest"});
Run Code Online (Sandbox Code Playgroud)

演示:https://jsfiddle.net/anderpo/x8ucc5ak/1/

  • 尝试添加一些解释 (2认同)