Javascript 无jQuery的平滑滚动定位链接

Javascript 无jQuery的平滑滚动定位链接,javascript,hyperlink,anchor,Javascript,Hyperlink,Anchor,是否可以使用平滑滚动来锚定链接,但不使用jQuery?我正在创建一个新站点,我不想使用jQuery从这里使用函数:修改它以修改属性(不仅仅是样式的属性),您可以尝试以下操作: function animate(elem, style, unit, from, to, time, prop) { if (!elem) { return; } var start = new Date().getTime(), timer = setInterv

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

从这里使用函数:修改它以修改属性(不仅仅是样式的属性),您可以尝试以下操作:

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

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

这显然需要根据您的问题的实际含义进行高度修改(比如当窗口散列改变时,或者类似的情况)

请注意,使用jQuery,它非常简单:

$(document).ready(function () {
    $("html, body").animate({
        scrollTop: $("#div5").offset().top
    }, 2000);
});
演示:


只要说…

CSS3转换使用
:target
选择器,就可以在没有任何JS攻击的情况下给出一个很好的结果。我只是在考虑是否要修改它,但是如果没有Jquery,它确实会变得有点混乱。有关详细信息,请参阅。

扩展此答案:

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

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

实际上,有一种更轻量级、更简单的方法可以做到这一点:

函数滚动到(元素){
滚动窗口({
行为:“平滑”,
左:0,,
顶部:element.offsetTop
});
}
document.getElementById(“按钮”).addEventListener('click',()=>{
scrollTo(document.getElementById(“8”));
});
div{
宽度:100%;
高度:200px;
背景色:黑色;
}
分区:第n个孩子(奇数){
背景色:白色;
}
钮扣{
位置:绝对位置;
左:10px;
顶部:10px;
}

按钮
使用此按钮:

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

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

演示

我目前最喜欢的卷轴库是因为它的大小很小(目前只有3.17kb)

scroll_to('#657kh54')

在未来,使用本机功能可能更有意义,但由于缺乏IE支持,目前大多数生产站点都必须使用多功能,因此我建议在所有情况下都使用Zencroll

使用polyfill平滑滚动行为

例如:

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

存储库:

它是从@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();
}
用法

scroll_to('#657kh54')
假设我们有10个分区:

<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>
您只需在单击事件中调用此函数即可(例如,单击按钮,然后滚动至div#9)

结果

scroll_to('#657kh54')

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

不幸的是,IE和Safari不支持scrollBehavior='smooth',截至2019年


使用
requestAnimationFrame
并支持easings和所有浏览器的Vanilla js变体:

const requestAnimationFrame=window.requestAnimationFrame||
window.webkitRequestAnimationFrame||
window.mozRequestAnimationFrame||
window.oRequestAnimationFrame||
window.msRequestAnimationFrame;
功能滚动至(至){
const start=window.scrollY | | window.pageYOffset
const time=Date.now()
常数持续时间=数学绝对值(开始到)/3;
(功能步骤(){
var dx=Math.min(1,(Date.now()-time)/持续时间)
var pos=启动+(至-启动)*easeOutQuart(dx)
窗口。滚动到(0,位置)
if(dx<1){
requestAnimationFrame(步骤)
}
})()
}
任何支持

在此处尝试以下代码:

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;
}
截至2019年,此属性仍不支持Safari或IE/Edge,因此要获得完整的交叉浏览器支持,您仍必须使用脚本。

基于for scroll选项,我们可以使用以下代码:

element.scrollTo({
  top: 100,
  left: 100,
  behavior: 'smooth'
});
实际上,
行为
键可以接受
平滑
自动
变量。第一个用于平滑运动,第二个用于单跳。
‍‍

对于尝试这样做的人:这是一个很棒的剧本,但不要期待任何缓和或美好的二人世界。这是一种原始的steppy动画。类似的尝试:&@mtness它在Firefox中运行良好(代码,可能不是演示)。您需要更新正在制作动画的元素,因为Firefox显然不喜欢更改
document.body
滚动条
(需要快速调试和谷歌搜索来解决这个问题)。尝试以下方法:(我将更新此帖子)我必须将
document.documentElement
传递到函数中,而不是
document.body
,以使其成为workdocument.body代表edge,document.documentElement代表chrome。唯一的问题是,您应该使用
element.getBoundingClientRect()而不是
element.offsetTop
.top+window.scrollY
@zdolny它现在可以在本机边缘工作,但对于IE,您需要一个polyfill-@ekfuhrmann,但它在Safari中工作吗?或者我也应该不关心Safari吗?试着添加一些解释解释:非常有趣的解决方案(+1),但目前IE中不支持!为什么不包括最重要的一点
html{scroll behavior:smooth;}
-非常简单,如果您可以避开IE支持,那么它可以起到很好的作用注意:这个示例的支持非常有限。如果不使用诸如Babel caniuse.com/#feat=Arrow函数这样的transpiler,任何版本的IE、Opera Mini、Blackberry浏览器、IE Mobile和QQ浏览器中的箭头函数都无法工作,而且行为“平滑”也严重缺乏支持。2019年,你无法使用querySelectorAll收听点击事件,它返回一个array.amem!