Chrome 中 scrollTo() 的 JavaScript 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15691569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 01:43:28  来源:igfitidea点击:

JavaScript issue with scrollTo() in Chrome

javascriptgoogle-chromescrollto

提问by atarax

I try to create a web page with a fixed navigation bar at the top that covers the content underneath. When loading the page with an anchor in the url the normal behaviour is that the page scrolls the anchor to the top of the window. But then that content is hidden under the navigation bar. So I try to solve this problem with JavaScript scrollTo(). My solution works fine with Firefox and Opera but not in Chrome. Please try the example. Any ideas how to fix this issue in Chrome? Thank you.

我尝试在顶部创建一个带有固定导航栏的网页,该导航栏覆盖下面的内容。在 url 中加载带有锚点的页面时,正常行为是页面将锚点滚动到窗口顶部。但随后该内容隐藏在导航栏下方。所以我尝试用 JavaScript scrollTo() 来解决这个问题。我的解决方案适用于 Firefox 和 Opera,但不适用于 Chrome。请试试这个例子。任何想法如何在 Chrome 中解决此问题?谢谢你。

test.htm:

测试.htm:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Test</title>
    <meta charset='UTF-8'>
    <style type='text/css'>
      #navi { position:fixed; left:0; top:0; width:100%; height:100px; background-color:yellow; }
      #spacer { background-color:cyan; height:100px; }
      #spacer2 { height:1000px; }
      .style1 { background-color:green; height:200px; }
    </style>
    <script type='text/javascript'>
      /* <![CDATA[ */
      function scrollAnchor() {  // doesn't work in Chrome
        var y = document.getElementById(window.location.hash.substr(1)).offsetTop - 110;
        window.scrollTo(0, y);
        //alert(y);
      }
      /* ]]> */
    </script>
  </head>
  <body id='top' onload='scrollAnchor();'>
    <div id='navi'>
      <a href='./test2.htm'>Menu</a>
    </div>
    <div id='main'>
      <div id='spacer'></div>
      <h3 id='1'>Heading 1</h3><p class='style1'></p>
      <h3 id='2'>Heading 2</h3><p class='style1'></p>
      <h3 id='3'>Heading 3</h3><p class='style1'></p>
      <h3 id='4'>Heading 4</h3><p class='style1'></p>
      <h3 id='5'>Heading 5</h3><p class='style1'></p>
      <h3 id='6'>Heading 6</h3><p class='style1'></p>
      <div id='spacer2'></div>
    </div>
  </body>
</html>

test2.htm:

test2.htm:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Test</title>
    <meta charset='UTF-8'>
  </head>
  <body>
    <a href='test.htm#1'>Heading 1</a>
    <a href='test.htm#2'>Heading 2</a>
    <a href='test.htm#3'>Heading 3</a>
    <a href='test.htm#4'>Heading 4</a>
    <a href='test.htm#5'>Heading 5</a>
    <a href='test.htm#6'>Heading 6</a>
  </body>
</html>

回答by Mark Ni

Chrome is so fast that your scrollTo() action fires beforeChrome's default scroll to html anchor event.

Chrome 速度如此之快,以至于您的 scrollTo() 操作会Chrome 的默认滚动到 html 锚点事件之前触发。

Give it a tiny delay by using

通过使用给它一个微小的延迟

setTimeout(function() {window.scrollTo(0, y);},1)


Or simply avoid using the actual element idas hash name

或者干脆避免使用实际元素 id作为哈希名称

instead of using

而不是使用

test.htm#6

测试.htm#6

use

利用

test.htm#link_6

test.htm#link_6

then you can get the real id by doing something like

然后你可以通过做类似的事情来获得真实的 id

window.location.hash.split('_')[1]

Hope it helps.

希望能帮助到你。

回答by mik13ST

I would suggest avoiding the use of JavaScript in favor of creating a dedicated anchor element and then offsetting it above the heading by at least your header height.

我建议避免使用 JavaScript,而是创建一个专用的锚元素,然后将它偏移到标题上方至少你的标题高度。

This has already been well described in https://stackoverflow.com/a/13184714/5951116.

这已经在https://stackoverflow.com/a/13184714/5951116 中得到了很好的描述。

Your code would then look something like this:

您的代码将如下所示:

<div id='navi'>
  <a href='./test2.htm'>Menu</a>
</div>
<div id='main'>
  <div id='spacer'></div>
  <div class='article-wrapper'>
    <a class='anchor' id='1'></a>
    <h3 id='1'>Heading 1</h3><p class='style1'></p>
  </div>
  <div class='article-wrapper'>
    <a class='anchor' id='2'></a>
    <h3 id='2'>Heading 2</h3><p class='style1'></p>
  </div>
  ...
</div>
#navi {
  height: 50px;
}

#main a.anchor {
    display: block;
    position: relative;
    top: -50px;
    visibility: hidden;
}

Or use CSS variables to remove as much tight coupling as possible:

或者使用 CSS 变量尽可能消除紧密耦合:

:root {
  --header-height: 50px;
}

#navi {
  height: var(--header-height);
}

#main a.anchor {
    display: block;
    position: relative;
    top: -var(--header-height);
    visibility: hidden;
}