滚动前自定义滚动始终返回顶部

时间:2014-01-02 00:02:13

标签: javascript custom-scrolling

我尝试制作一个自定义滚动脚本,从我的网站中的一个块到另一个块但是当我点击我的下一个按钮时,滚动总是跳到顶部。我不知道为什么总是如此。

这是我的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);
    }
}

这里我在jsbin上做了一个例子:http://jsbin.com/ehIZAya/

感谢阅读。

1 个答案:

答案 0 :(得分:2)

问题:页面跳到顶部

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

  • This link相当于href="#20898954"(因为20898954是此答案的ID);将导致您的浏览器跳到此答案的顶部
  • This link相当于href="#";它会使您的浏览器跳转到页面顶部

要解决此问题,您有两种选择:

  1. 删除每个锚点的href属性。不幸的是,这种方法删除了所有样式(它看起来像普通文本),这可能会令人困惑。相反,我更喜欢......
  2. 使用onclick处理preventDefault()功能中的点击事件本身。

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

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


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

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

    问题在于someNumber。您可以输入一个整数值(即500),每个链接将滚动到页面上的相同位置(500px)。您可以输入一个整数* i(即500 * i),每个链接将滚动到500px(0px,500px,1000px等)的倍数。但我选择使用名为scroll-target的自定义属性来使其更加可自定义。

    每个锚定义为<a class="link" href="#" scroll-target="500">,其中500可能是任何值。要获取自定义属性,请使用element.getAttribute("attributeName")。所以,我们离开了:

    for (var i = 0; i < links.length; i++) {
        links[i].onclick = function(e) {
            e.preventDefault();
            myscroll(this.getAttribute("scroll-target"));
        };
    };
    

    要将此应用于您的代码,请确保定义每个锚<a class="link" href="#" scroll-target="500">,将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);
        }
    }
    

    如果您想要向上滚动,您可能还希望为当前可见区域的顶部添加相等和相反的条件,如果您想要向上滚动。