4

我有一个 HTML 页面,其中包含指向内容包装器中的子部分的链接,该内容包装器定位/调整大小并用于overflow:auto显示滚动条。子部分的链接有效(导致内容滚动到正确的高度),但使用后退按钮不会重新滚动到Firefox v13、IE v9 或 Opera v11 中的正确部分(它在 Chrome v20 和 Safari v5 中有效)。

鉴于我不能彻底改变我的 CSS(我需要使用定位、大小、溢出的内容),我该如何解决这个问题?

可以接受涉及 JavaScript/jQuery 的解决方案,但最好使用纯 CSS 修复。

测试页面:phrogz.net/tmp/backing...containers.html

<!DOCTYPE html>
<html><head><title>Backing into Subpage Anchors in Overflowed Containers</title>
  <style type="text/css">
    #site-nav { position:fixed; width:10em; top:0; left:0 }
    #contents { position:fixed; top:3em; bottom:5em; left:11em; right:0;
                overflow:auto; background:#fed }
    div            { height:15em }
    div:last-child { height:55em }
  </style>
</head><body>

<article id="contents">
  <div>
    <h1 id="a">Section A</h1>
    <p>Navigate to the different sections at left, and then press the Back button.</p>
  </div>
  <div><h1 id="b">Section B</h1></div>
  <div><h1 id="c">Section C</h1></div>
</article>
<ul id="site-nav">
  <li><a href="#a">Section A</a></li>
  <li><a href="#b">Section B</a></li>
  <li><a href="#c">Section C</a><ul>
</ul>

</body></html>

先前提交的 Firefox 错误:https
://bugzilla.mozilla.org/show_bug.cgi?id=391664 引用为 Opera 错误:DSK-365451@bugs.opera.com

4

3 回答 3

2

我使用 jQuery、@barius 建议的hashchange 插件和以下代码解决了这个问题:

jQuery(function($){
  var $content = $('#contents');
  $(window).hashchange(scrollHashIntoView);

  function scrollHashIntoView(){
    // Ensure that the ID I'm looking for is within my scrolling content
    var offset = $content.find(location.hash).offsetRelativeTo($content);
    $content.scrollTop( offset ? offset.top : 0 );
  }
});

// Find the offset of an element relative to some ancestor
jQuery.fn.offsetRelativeTo = function(el){
  var $el=$(el), o=this.offset(), o2=$el.offset();
  if (o){
    o.top  -= o2.top  - $el.scrollTop();
    o.left -= o2.left - $el.scrollLeft();
  }
  return o;
}

offsetRelativeTo()对于我更复杂的情况,当其中一个子锚点碰巧在position:relative父级内(它本身在滚动内容内)时,该代码是必要的。

我创建了scrollHashIntoView()一个单独的函数,因为 (a) 它有助于自我记录行为,并且 (b) 它允许我在需要时单独调用它,以及 (c) 它将工作的实现与简洁的事件注册和他们的行动。

一个更强大的解决方案(处理嵌套滚动区域的不太可能但可能的情况)将找到 id 并沿着offsetParents 的树向上走,并在适当的时候将每个滚动到视图中。

于 2012-06-06T18:21:23.613 回答
1

我认为您可以使用 onhashchange 事件。它仅由较新的浏览器支持,但可以使用插件,例如http://benalman.com/projects/jquery-hashchange-plugin/

当 hash 发生变化时,您可以通过 ID 查找元素并更改容器的 scrollTop 属性。像这样的东西:

$(function(){
    $(window).hashchange(function(){
        var elem = $(location.hash);
        if (elem.count() > 0) {
            elem.offsetParent().animate({scrollTop: elem.position().top});
        }
    });
});
于 2012-06-06T17:21:17.003 回答
-1

我也打算推荐这个onhashchange活动,但旧版浏览器不支持它。一个简单的解决方案是简单地使用页面上第一个锚点的哈希值,如果您没有哈希值,则自动将其设置为该值。

$(function() {
    if(window.location.hash == '') {
        window.location.hash = $("a[href^='#']:first").attr('href');
    }
});
于 2012-06-06T17:35:58.697 回答