2

I wish to update the fragment identifier on the url as the user is scrolling so that it matches the element at the top of the screen.

Is there a way to do that?

Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
zcaudate
  • 13,998
  • 7
  • 64
  • 124
  • See http://stackoverflow.com/questions/5315659/jquery-change-hash-while-scolling-down-page (Not quite a duplicate, since that question allows jQuery and also wanted to update a menu item, but definitely a near-dupe) – Ben Lee May 09 '13 at 03:50

1 Answers1

1

I think this is what you want: http://fiddle.jshell.net/hainawa/u5e2s/show/light/

HTML:

<div id="section-1" class="section">section-1 <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /></div>
<div id="section-2" class="section">section-2 <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /></div>
<div id="section-3" class="section">section-3 <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /></div>
<div id="section-4" class="section">section-4 <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /></div>

JavaScript(rely on jQuery):

$(function() {
    var $secitions = $(".section"),
        topArrays = {};

    $secitions.each(function(i, ele) {
        var $section = $secitions.eq(i),
            secTop = $section.offset().top;
        topArrays[secTop] = $section.attr("id");
    });

    $(document,window).scroll(function(e) {
        var $ele = $(e.currentTarget),
            currentTop = $ele.scrollTop(),
            currentHash, arrayHash, topDiff;

        for(var i in topArrays) {
            arrayHash = topArrays[i];
            topDiff = currentTop - i;
            currentHash = document.location.hash;
            //It's impossable to scroll to the section without any offset
            if(topDiff > 0 && topDiff < 100 && currentHash != arrayHash) {
                document.location.hash = arrayHash;
            }
        }
    });
});

But there are some problems here:

  1. if you are using image lazy-loading,it won't work;
  2. The code's performance isn't very high;
  3. history.pushState is better then assigning value to location.hash,but not every browser support it.

If anyone has better solution,I'll be grateful,cause I've been thinking about it for a long time.

Daidai
  • 547
  • 4
  • 13
  • What happens if you resize the window? – zcaudate May 10 '13 at 05:31
  • @zcaudate It will cause problems if you're using the responsive design or take percent/em as value in width.In this case,you should listen "resize" for window and update topArrays and hash of location when "resize" are triggered. – Daidai May 10 '13 at 05:52