Javascript 自定义滚动总是在滚动前返回顶部

Javascript 自定义滚动总是在滚动前返回顶部,javascript,custom-scrolling,Javascript,Custom Scrolling,我试图制作一个自定义的滚动脚本,在我的网站上从一个块转到另一个块,但当我点击下一步按钮时,滚动总是跳到顶部。我不知道为什么它总是这样 以下是我的javascript代码: function myscroll(i) { if (document.body.scrollTop + window.innerHeight > document.body.scrollHeight - 50) { document.body.scrollTop += 1;

我试图制作一个自定义的滚动脚本,在我的网站上从一个块转到另一个块,但当我点击下一步按钮时,滚动总是跳到顶部。我不知道为什么它总是这样

以下是我的javascript代码:

function myscroll(i)
{
    if (document.body.scrollTop + window.innerHeight > document.body.scrollHeight - 50)
    {
        document.body.scrollTop += 1;
        if (document.body.scrollTop + window.innerHeight < document.body.scrollHeight)
            setTimeout(function() { myscroll(i) }, 10);
    }
    else if (document.body.scrollTop < i - 100)
    {
        document.body.scrollTop += 10;
        if (document.body.scrollTop + window.innerHeight < document.body.scrollHeight)
            setTimeout(function() { myscroll(i) }, 10);
    }
    else if (document.body.scrollTop < i - 50)
    {
        document.body.scrollTop += 5;
        if (document.body.scrollTop + window.innerHeight < document.body.scrollHeight)
            setTimeout(function() { myscroll(i) }, 10);
    }
    else if (document.body.scrollTop < i)
    {
        document.body.scrollTop += 1;
        if (document.body.scrollTop + window.innerHeight < document.body.scrollHeight)
            setTimeout(function() { myscroll(i) }, 10);
    }
}
函数myscroll(i)
{
if(document.body.scrollTop+window.innerHeight>document.body.scrollHeight-50)
{
document.body.scrollTop+=1;
if(document.body.scrollTop+window.innerHeight
在这里,我在jsbin上做了一个示例:


感谢阅读。

问题:页面跳转到顶部

页面跳转到顶部是因为
href=“#”
导致浏览器查找ID为
#
后面的元素。例如:

  • 相当于
    href=“#20898954”
    (因为
    20898954
    是这个答案的ID);将导致您的浏览器跳转到此答案的顶部
  • 相当于
    href=“#”
    ;这将导致浏览器跳转到页面顶部
要解决此问题,您有两个选择:

  • 删除每个锚点的
    href
    属性。不幸的是,此方法删除了所有样式(看起来像普通文本),这可能会造成混淆。相反,我更喜欢
  • 使用
    preventDefault()
    onclick
    函数中处理单击事件本身

  • 问题:
    document.body.scrollTop
    始终等于0。在代码中,第一个
    else if
    作为无限循环执行,因为它是第一个计算为true的条件。问题是您将像素添加到
    document.body.scrollTop
    ,该值保持为0,因此,第二个条件实际上总是调用自身再次运行

    document.body.scrollTop
    替换为
    document.documentElement.scrollTop
    ,以准确读取可查看窗口的当前顶部,并正确设置它


    要防止自动跳转到页面顶部,可以使用
    preventDefault()
    。假设每个锚点都有类
    链接

    var links = document.getElementsByClassName("link")
    for (var i = 0; i < links.length; i++) {
        links[i].onclick = function(e) {
            e.preventDefault();
            myscroll(someNumber);
        };
    };
    

    要将此应用于代码,请确保每个锚点都已定义,并用所需的实际值替换500。您也可以使用除“link”之外的类名,但如果使用,请确保也替换我脚本第二行中的类名

    在页面加载时,它会提醒一些值。滚动到随机位置,然后刷新页面。注意哪些值会改变,哪些保持不变。这样做几次,直到你明白

    Javascript:

    alert("document.body.scrollTop = " + document.body.scrollTop + "\ndocument.documentElement.scrollTop = " + document.documentElement.scrollTop + "\ndocument.body.scrollHeight = " + document.body.scrollHeight + "\nwindow.innerHeight = " + window.innerHeight);
    var links = document.getElementsByClassName("link")
    for (var i = 0; i < links.length; i++) {
        links[i].onclick = function(e) {
            e.preventDefault();
            myscroll(this.getAttribute("scroll-target"));
        };
    };
    
    function myscroll(i) {
        // If bottom of currently viewable area is less than 50px from bottom of page
        if (document.documentElement.scrollTop + window.innerHeight > document.body.scrollHeight - 50) {
            console.log("1");
            document.documentElement.scrollTop += 1;
            if (document.documentElement.scrollTop + window.innerHeight < document.body.scrollHeight)
                setTimeout(function () {
                    myscroll(i)
                }, 10);
        // If top of currently viewable area is 101px or more above target
        } else if (document.documentElement.scrollTop < i - 100) {
            console.log("2");
            document.documentElement.scrollTop += 10;
            if (document.documentElement.scrollTop + window.innerHeight < document.body.scrollHeight)
                setTimeout(function () {
                    myscroll(i)
                }, 10);
        // If top of currently viewable area is 51-100px above target
        } else if (document.documentElement.scrollTop < i - 50) {
            console.log("3");
            document.documentElement.scrollTop += 5;
            if (document.documentElement.scrollTop + window.innerHeight < document.body.scrollHeight)
                setTimeout(function () {
                    myscroll(i)
                }, 10);
        // If top of currently viewable area is 49px or less above target (including below target)
        } else if (document.documentElement.scrollTop < i) {
            console.log("4");
            document.documentElement.scrollTop += 1;
            if (document.documentElement.scrollTop + window.innerHeight < document.body.scrollHeight)
                setTimeout(function () {
                    myscroll(i)
                }, 10);
        }
    }
    
    警报(“document.body.scrollTop=“+document.body.scrollTop+”\ndocument.documentElement.scrollTop=“+document.documentElement.scrollTop+”\ndocument.body.scrollHeight=“+document.body.scrollHeight+”\nWindows.innerHeight=“+window.innerHeight”);
    var links=document.getElementsByClassName(“链接”)
    对于(变量i=0;idocument.body.scrollHeight-50){
    控制台日志(“1”);
    document.documentElement.scrollTop+=1;
    if(document.documentElement.scrollTop+window.innerHeight
    如果要向上滚动,可能还需要为当前可视区域的顶部超过/低于目标添加相等和相反的条件

    alert("document.body.scrollTop = " + document.body.scrollTop + "\ndocument.documentElement.scrollTop = " + document.documentElement.scrollTop + "\ndocument.body.scrollHeight = " + document.body.scrollHeight + "\nwindow.innerHeight = " + window.innerHeight);
    var links = document.getElementsByClassName("link")
    for (var i = 0; i < links.length; i++) {
        links[i].onclick = function(e) {
            e.preventDefault();
            myscroll(this.getAttribute("scroll-target"));
        };
    };
    
    function myscroll(i) {
        // If bottom of currently viewable area is less than 50px from bottom of page
        if (document.documentElement.scrollTop + window.innerHeight > document.body.scrollHeight - 50) {
            console.log("1");
            document.documentElement.scrollTop += 1;
            if (document.documentElement.scrollTop + window.innerHeight < document.body.scrollHeight)
                setTimeout(function () {
                    myscroll(i)
                }, 10);
        // If top of currently viewable area is 101px or more above target
        } else if (document.documentElement.scrollTop < i - 100) {
            console.log("2");
            document.documentElement.scrollTop += 10;
            if (document.documentElement.scrollTop + window.innerHeight < document.body.scrollHeight)
                setTimeout(function () {
                    myscroll(i)
                }, 10);
        // If top of currently viewable area is 51-100px above target
        } else if (document.documentElement.scrollTop < i - 50) {
            console.log("3");
            document.documentElement.scrollTop += 5;
            if (document.documentElement.scrollTop + window.innerHeight < document.body.scrollHeight)
                setTimeout(function () {
                    myscroll(i)
                }, 10);
        // If top of currently viewable area is 49px or less above target (including below target)
        } else if (document.documentElement.scrollTop < i) {
            console.log("4");
            document.documentElement.scrollTop += 1;
            if (document.documentElement.scrollTop + window.innerHeight < document.body.scrollHeight)
                setTimeout(function () {
                    myscroll(i)
                }, 10);
        }
    }