在溢出的内容中备份到子页面锚点

时间:2012-06-06 16:26:39

标签: javascript jquery html css

我有一个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 Bug:DSK-365451@bugs.opera.com

3 个答案:

答案 0 :(得分:2)

我使用jQuery,@ barius建议的hashchange plugin以及以下代码解决了这个问题:

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并沿offsetParent s的树向上走,并在适当时将每个滚动到视图中。

答案 1 :(得分:1)

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

当散列更改时,您可以按ID查找元素并更改容器的scrollTop属性。像这样:

$(function(){
    $(window).hashchange(function(){
        var elem = $(location.hash);
        if (elem.count() > 0) {
            elem.offsetParent().animate({scrollTop: elem.position().top});
        }
    });
});

答案 2 :(得分:-1)

我还会推荐onhashchange事件,但旧浏览器不支持此事件。一个简单的解决方案是简单地使用页面上第一个锚点的哈希值,并在没有哈希值的情况下自动将其设置为。

$(function() {
    if(window.location.hash == '') {
        window.location.hash = $("a[href^='#']:first").attr('href');
    }
});