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

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

谢谢阅读。

4

1 回答 1

2

问题:页面跳转到顶部

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

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

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

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

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

替换document.body.scrollTopdocument.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),每个链接将滚动到页面上的相同位置(500 像素)。您可以输入一个整数 * i(即500 * i),每个链接将滚动到 500 像素的倍数(0 像素、500 像素、1000 像素等)。但我选择使用一个名为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 替换为您想要的实际值。您也可以使用“链接”以外的类名,但如果这样做,请确保也替换脚本第二行中的类名。

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

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

如果您想向上滚动,您可能还想为当前可见区域的顶部超过/低于目标添加相等和相反的条件。

于 2014-01-03T07:45:39.677 回答