简体   繁体   English

自定义滚动始终在滚动之前回到顶部

[英]Custom scrolling always go back to top before scrolling

i tried to make a custom scrolling script that goes from one block to another in my website but when i click on my next button, the scrolling always jump to the top. 我试图制作一个自定义的滚动脚本,该脚本在我的网站中从一个块跳转到另一个块,但是当我单击下一个按钮时,滚动始终跳到顶部。 I don't know why it always do that. 我不知道为什么总是这样。

Here is my javascript code : 这是我的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);
    }
}

here i made an exemple on jsbin : http://jsbin.com/ehIZAya/ 在这里,我以jsbin为例: http ://jsbin.com/ehIZAya/

Thanks for reading. 谢谢阅读。

Problem: Page jumping to top 问题:页面跳转到顶部

The page jumps to the top because href="#" causes your browser to look for an element with ID of what comes after the # . 该页面跳至顶部,因为href="#"会使您的浏览器查找ID在#之后的元素。 For example: 例如:

  • This link is equivalent to href="#20898954" (since 20898954 is the ID of this answer); 该链接等效于href="#20898954" (因为20898954是此答案的ID); will cause your browser to jump to the top of this answer 将导致您的浏览器跳至该答案的顶部
  • This link is equivalent to href="#" ; 该链接等效于href="#" ; it will cause your browser to jump to the top of the page 这将导致您的浏览器跳至页面顶部

To fix this, you have two choices: 要解决此问题,您有两种选择:

  1. Remove each anchor's href attribute. 删除每个锚点的href属性。 Unfortunately, this method removes all styling (and it looks like ordinary text), which can be confusing. 不幸的是,此方法删除了所有样式(看起来像普通文本),这可能会造成混淆。 Instead, I prefer to... 相反,我更喜欢...
  2. Handle the click event itself in the onclick function with preventDefault() . 使用preventDefault()onclick函数中处理click事件本身。

Problem: document.body.scrollTop always equals 0. In your code, the first else if executes as an infinite loop, since it is the first condition that evaluates to true. 问题: document.body.scrollTop始终等于0。在您的代码中,第一个else if执行为无限循环,因为它是第一个求值为true的条件。 The problem is that you add pixels to document.body.scrollTop , which remains 0, and thus, the second condition always, in effect, calls itself to run again. 问题是您将像素添加到document.body.scrollTop ,该像素保持为0,因此,第二个条件始终实际上会再次调用自身以再次运行。

Replace document.body.scrollTop with document.documentElement.scrollTop for accurate readings of the current top of the viewable window, and to set it correctly. 更换document.body.scrollTopdocument.documentElement.scrollTop的可视窗口的当前最高的精确读数,并正确设置它。


To prevent the automatic jump to the top of the page, you can use preventDefault() . 为了防止自动跳转到页面顶部,可以使用preventDefault() Assume each anchor has class link : 假设每个锚都有类link

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

The problem there is someNumber . 问题是someNumber You could enter an integer value (ie 500 ), and each link would scroll to the same place on the page (500px). 您可以输入一个整数值(即500 ),每个链接将滚动到页面上的同一位置(500px)。 You could enter an integer * i (ie 500 * i ), and each link would scroll to a multiple of 500px (0px, 500px, 1000px, etc.). 您可以输入一个整数* i(即500 * i ),每个链接将滚动到500px(0px,500px,1000px等)的倍数。 But I chose to make this a little more customizable than that, with a custom attribute called scroll-target . 但是我选择使用名为scroll-target的自定义属性,使其比此更具可定制性。

Each anchor is defined <a class="link" href="#" scroll-target="500"> , where 500 might be any value. 每个锚定义为<a class="link" href="#" scroll-target="500"> ,其中500可以是任何值。 To get a custom attribute, use element.getAttribute("attributeName") . 要获取自定义属性,请使用element.getAttribute("attributeName") And so, we're left with: 因此,我们剩下:

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

To apply this to your code, make sure each anchor is defined <a class="link" href="#" scroll-target="500"> , replacing 500 with the actual value you want. 要将其应用于您的代码,请确保定义了每个锚点<a class="link" href="#" scroll-target="500"> ,并用所需的实际值替换500。 You can also use a class name other than "link", but if you do, make sure you replace the class name in the second line of my script also. 您也可以使用“链接”以外的其他类名,但是如果这样做,请确保也替换脚本第二行中的类名。

On page load, it alerts a few values. 在页面加载时,它会提示一些值。 Scroll to random places, and refresh the page. 滚动到任意位置,然后刷新页面。 Take note which values change, and which remain the same. 请注意哪些值会更改,哪些保持不变。 Do this a few times until you understand. 这样做几次,直到您了解为止。

Javascript: 使用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);
    }
}

You might also want to add equal and opposite conditions for the top of the currently-viewable area being past/below the target, if you ever want to scroll upwards. 如果您想向上滚动,则可能还希望为当前可查看区域的顶部超过或低于目标添加相等和相反的条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM