平滑滚动锚链接没有jQuery

时间:2013-07-18 20:16:55

标签: javascript hyperlink anchor

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

17 个答案:

答案 0 :(得分:50)

扩展此答案: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);
}

如果你的div有id =&#34;页脚&#34;

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

在您运行滚动的脚本中,您可以运行它,

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

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

答案 1 :(得分:40)

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

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

DEMO: https://jsfiddle.net/zpu16nen/

确保您将窗口调整得足够小,以便实际上有一个滚动条,并且可以滚动到第5个div。

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

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

请注意,使用jQuery,它就像:

一样简单
$(document).ready(function () {
    $("html, body").animate({
        scrollTop: $("#div5").offset().top
    }, 2000);
});

DEMO: http://jsfiddle.net/7TAa2/1/

只是说......

答案 2 :(得分:21)

实际上,有更轻量级和简单的方法: 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>

答案 3 :(得分:5)

使用此:

pipenv

DEMO https://jsfiddle.net/anderpo/x8ucc5ak/1/

答案 4 :(得分:4)

使用:target选择器的CSS3过渡可以在没有任何JS黑客攻击的情况下提供良好的结果。我只是在考虑是否要改变它,但没有Jquery它确实有点混乱。有关详细信息,请参阅this question

答案 5 :(得分:2)

使用requestAnimationFrame且易于使用且支持所有浏览器的Vanilla js变体:

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

任何easing支持!

答案 6 :(得分:2)

纯轻量级JavaScript库:smooth-scroll on github

答案 7 :(得分:1)

使用polyfill的平滑滚动行为...

示例:

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

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

答案 8 :(得分:1)

我最喜欢的滚动库目前是Zenscroll,因为wide range of features和小尺寸(目前只有3.17kb)。

将来使用原生scrollIntoView功能可能会更有意义,但由于缺乏IE支持,因此今天大多数生产网站必须对其进行填充,我建议使用Zenscroll相反,在所有情况下。

答案 9 :(得分:0)

它是@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);
    }
}

答案 10 :(得分:0)

这是纯JavaScript 中的简单解决方案。它利用CSS属性 scroll-behavior:smooth

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>

我们可以滚动到选择的ID

scroll_to('#657kh54')

您只需在您的点击事件上调用此功能(例如,点击按钮,然后滚动至第9格)。

结果

enter image description here

当然,它在现实生活中看起来更加流畅。

FIDDLE

不幸的是,从 2019

开始,IE和Safari不支持scrollBehavior ='smooth'

enter image description here MDN Web Docs

答案 11 :(得分:0)

您可以使用此javascript库为所有内部链接添加平滑滚动。 您也可以添加配置,以提供忽略的链接。 你可以在这里详细了解一下。 https://codingninjascodes.github.io/SmoothScrollJs/

答案 12 :(得分:0)

对于2019年的所有人, 首先,您添加一个事件监听器

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

然后您将元素定位为目标并顺利进行

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

答案 13 :(得分:0)

这是一个很老的问题,但是我认为必须说,当今CSS支持平滑滚动,所以不需要任何脚本:

html {
  scroll-behavior: smooth;
}

截至2019年,此属性仍不支持Safari或IE / Edge,因此要获得全面的跨浏览器支持,您仍然必须使用脚本。

答案 14 :(得分:0)

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

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

实际上,behavior键可以接受smoothauto变量。首先是平稳运动,其次是单跳。

答案 15 :(得分:0)

要获得更全面的平滑滚动方法列表,请参阅我的回答 here


要在精确的时间内滚动到某个位置,可以使用 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 library,它处理垂直和水平平滑滚动、在其他容器元素内部滚动、不同的缓动行为、从当前位置相对滚动等等。

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>

现代浏览器支持 scroll-behavior CSS property,可以用来使文档滚动流畅(无需 JavaScript)。为此,可以通过为锚标记指定 href# 加上要滚动到的元素的 id 来使用锚标记。您还可以为特定容器(如 scroll-behavior)设置 div 属性,使其内容平滑滚动。

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

答案 16 :(得分:-1)

在此处尝试此代码:

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