Change url when manually scrolled to an anchor?

后端 未结 6 1740
失恋的感觉
失恋的感觉 2020-11-30 01:53

By Default, if I have anchors in my website, then the URL on the address bar is changed, when I click on a link (ie. www.mysite.com/#anchor)

Is it possible to change

相关标签:
6条回答
  • 2020-11-30 02:25

    Plain js version While researching how to update the URL based off positions of HTML section elements on the screen, I kept finding this thread so I hope this is a good place to post this.

    This function loops over the HTML section elements.

            function updateFragId() {
            var len = sections.length;
              for (var i = 0; i < len; i++) {
                var id = sections[i].id;
    

    Collects the Y scroll position relative to the viewport.

                var rect = sections[i].getBoundingClientRect().y;
    

    convert the two arrays into an object

                var pageData = {id:id, rect:rect};
    

    set a range for the code to trigger in between. Here it will trigger when the top of the section element is between -200px to 400px

                if (pageData.rect > -200 && pageData.rect < 400) {
    

    only run once by making sure the pageData.id and location.hash dont already match. This stops it from flooding your browser with events.

            if (pageData.rect > -100 && pageData.rect < 100) {
                if (pageData.id !== location.hash.substr(1)) {
                    fragmentId = pageData.id;
                    setActiveLink(fragmentId);
                  } else {
                    return;
                }
              }
            }
          }
    
        window.addEventListener('scroll', updateFragId);
    

    I use a debouncer on this block of code with another block to set the active link. But this is just how to track the # anchors.

    0 讨论(0)
  • 2020-11-30 02:28

    you can use HTML 5 pushstate to change the URL in the address bar

    window.history.pushstate


    1. https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history
    2. How can I use window.history.pushState 'safely'
    0 讨论(0)
  • 2020-11-30 02:35

    You can bind to the jQuery scroll event (http://api.jquery.com/scroll/) and on each call of the callback called, check how far on the document the user has scrolled by checking this value: .scrollTop (http://api.jquery.com/scrollTop/) and set the anchor by manipulating te location.hash object (http://www.w3schools.com/jsref/prop_loc_hash.asp).

    It would be something like this:

    // Checks if the passed element is visible on the screen after scrolling
    // source: http://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling
    function isScrolledIntoView(elem) {
      var docViewTop = $(window).scrollTop();
      var docViewBottom = docViewTop + $(window).height();
    
      var elemTop = $(elem).offset().top;
      var elemBottom = elemTop + $(elem).height();
    
      return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    }
    
    $('#document').scroll(function(e) {
      var anchors = $('.anchor');
      for (var i = 0; i < anchors.length; ++i) {
        if (isScrolledIntoView(anchors[i])){
          var href = $(anchors[i]).attr('href');
          location.hash = href.slice(href.indexOf('#') + 1);
          break;
        }
      }
    });
    

    You could be more precise, if you sort the anchors after selecting them, so that the first visible anchor will be set always.

    0 讨论(0)
  • 2020-11-30 02:42

    Try using this jquery plugin: Scrollorama. It has tons of cool features and you can use window.location.hash to update your browsers hash.

    Alternatively, you can add a "scroll" event to check when an anchor is reached.

    Here is a working fiddle to illustrate the event: http://jsfiddle.net/gugahoi/2ZjWP/8/ Example:

    $(function () {
        var currentHash = "#initial_hash"
        $(document).scroll(function () {
            $('.anchor_tags').each(function () {
                var top = window.pageYOffset;
                var distance = top - $(this).offset().top;
                var hash = $(this).attr('href');
                // 30 is an arbitrary padding choice, 
                // if you want a precise check then use distance===0
                if (distance < 30 && distance > -30 && currentHash != hash) {
                    window.location.hash = (hash);
                    currentHash = hash;
                }
            });
        });
    });
    
    0 讨论(0)
  • 2020-11-30 02:42

    I think you need to do something like this. Not tried in action

    var myElements = $("div.anchor"); // You target anchors
    $(window).scroll(function(e) {
        var scrollTop = $(window).scrollTop();
        myElements.each(function(el,i) {
            if ($(this).offset().top > scrollTop && $(myElements[i+1]).offset().top < scrollTop) {
                 location.hash = this.id;
            }
        });
    });`
    
    0 讨论(0)
  • 2020-11-30 02:47
    1. Bind a handler to jquery scroll event.
    2. Check if an anchor is currently visible on-screen with this jquery script.
    3. Use pushstate or set location (probably will cause jumps)
    0 讨论(0)
提交回复
热议问题