繁体   English   中英

返回到溢出内容的子页面锚点

[英]Backing into subpage anchors in overflowed content

我有一个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

我使用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;
}

对于我更复杂的情况,当子锚之一恰好位于position:relative父对象(本身在滚动内容之内)中时,需要offsetRelativeTo()代码。

我使scrollHashIntoView()是一个单独的函数,因为(a)它有助于自我记录行为,并且(b)它允许我在需要时分别调用它,并且(c)它使工作的实现与简洁分开事件注册及其行为。

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

我认为您可以使用onhashchange事件。 只有较新的浏览器才支持此功能,但可以使用插件,例如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});
        }
    });
});

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

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

暂无
暂无

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

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