【问题标题】:jQuery change hash (fragment identifier) while scrolling down page向下滚动页面时jQuery更改哈希(片段标识符)
【发布时间】:2011-07-15 23:57:49
【问题描述】:

我正在建立一个单页机网站。例如。每页(共 5 页)都在一个大页面上,主菜单固定在顶部。当您单击菜单链接时,它会将您向下滑动到该页面的锚标记,并且单击的菜单项会获得“活动” CSS 类。

我现在想做的是允许用户自己滚动,但仍然有菜单“活动”项和 URL 哈希更改。

所以我的问题基本上是我如何知道用户何时向下滚动到不同的页面,以便我可以更新菜单和 URL 哈希(片段标识符)。

谢谢

【问题讨论】:

  • 最好的最新方法是使用 HTML5 History API。有关详细信息,请参阅this related question

标签: javascript jquery url


【解决方案1】:

可能,但您的页面有一个要求(我的解决方案才能工作):

您的页面必须在具有唯一 ID 的 div(或其他部分)中分隔(我希望您不要使用锚点 <a>'s)

你可以使用这样的代码:

$(document).bind('scroll',function(e){
    $('section').each(function(){
        if (
           $(this).offset().top < window.pageYOffset + 10
//begins before top
        && $(this).offset().top + $(this).height() > window.pageYOffset + 10
//but ends in visible area
//+ 10 allows you to change hash before it hits the top border
        ) {
            window.location.hash = $(this).attr('id');
        }
    });
});

像这样的html

<section id="home">
  Home
</section>
<section id="works">
  Works
</section>
<section id="about">
  About
</section>

【讨论】:

  • 能否请您发布将进入“window.location.hash”部分的代码。我使用了 window.location.hash = $(this).attr('href') ,但我得到了每个哈希的 #undefined 。谢谢
  • @suludi 那些部分没有hrefid
  • 抱歉,我自己立即注意到了这一点。但问题是它根本不允许我滚动。我无法在我正在处理的网站上滚动,但是脚本太多(滚动的),所以我想可能是冲突。所以我创建了一个包含 4 个部分的简单干净页面,但它仍然不允许我滚动。这是链接,非常感谢您的帮助:madebym.me/test/scroll-hash
  • +1 如果您想更改滚动时的哈希值,但又不想将哈希值保存在用户历史记录中,我发现这样可以:var urlId = '#' + $(this).attr('id'); history.replaceState(null, null, urlId);
  • 往回滚动怎么样?向下滚动时效果很好,当h1 到达顶部时它会更改哈希(我将部分更改为h1),但是当我向上滚动时,当我通过h1
【解决方案2】:

对于修复高度部分的内容,我有同样的问题,它将根据滚动更改哈希。不知何故,此代码在 Chrome 之外的其他浏览器上不起作用。并且还要在滚动中操作 DOM,然后该事件需要很长时间才能获得进程参考 http://www.smashingmagazine.com/2013/06/10/pinterest-paint-performance-case-study/ 这是我如何解决这个问题的示例代码

 (function () {
    // Find all  top,bottom and Hash of each sections,
    // Do this only if the section height remain the same always
    // Move this into the step() if your section height does change.
    // e.g. browser resize
    //
    var section = $.map($("section"), function (e) {
        var $e = $(e);
        var pos = $e.position();
        return {
            top: pos.top,
            bottom: pos.top + $e.height(),
            hash: $e.attr('id')
        };
    });

    //Checking scroll 
    var top = null;
    var changed = false;
    var currentHash = null;

    $(window).scroll(function () {
        var newTop = $(document).scrollTop();

        changed = newTop != top;
        if (changed) {
            top = newTop;
        }

    });

    // You wouldn't want to keep checking the scroll state as
    // it affects the browser performance when it's accessing
    // DOM and reduce your FPS (Frame per Seconds) for scrolling
    // 
    function step() {
        if (!changed) {
            // Top did not change
            return setTimeout(step, 200);
        }
        var count = section.length;
        var p;

        while (p = section[--count]) {
            if (p.top >= top || p.bottom <= top) {
                continue;
            }
            if (currentHash == p.hash) {
                break;
            }
            var scrollTop = $(document).scrollTop();
            window.location.hash = currentHash = p.hash;
            // prevent browser to scroll
            $(document).scrollTop(scrollTop);
        }
        setTimeout(step, 200);
    }
    setTimeout(step, 200);
})(); 

Demo

【讨论】:

    【解决方案3】:

    您正在寻找.scroll() 事件处理程序

    【讨论】:

      【解决方案4】:

      使用 jquery,您可以使用 scrollTop 方法找到滚动位置,然后比较它来判断页面上元素的位置,从而确定它们在页面上的位置并相应地更新。

      【讨论】:

        猜你喜欢
        • 2011-07-07
        • 1970-01-01
        • 2011-05-11
        • 1970-01-01
        • 2020-04-05
        • 2013-03-31
        • 2014-12-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多