Javascript 手动滚动到锚点时更改 url?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14660580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 17:31:55  来源:igfitidea点击:

Change url when manually scrolled to an anchor?

javascriptjquery

提问by r1987

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)

默认情况下,如果我的网站中有锚点,则当我单击链接(即 www.mysite.com/#anchor)时,地址栏上的 URL 会更改

Is it possible to change the URL in the address bar instantly when I scroll to an anchor? Or have a long document with multiple anchors and the url changes on address bar, when I hit a new anchor?

当我滚动到锚点时,是否可以立即更改地址栏中的 URL?或者当我点击一个新的锚点时,有一个包含多个锚点的长文档并且地址栏上的 url 会发生变化?

回答by Gustavo Htheitroadisch

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

尝试使用这个 jquery 插件:Scrollorama。它有很多很酷的功能,你可以window.location.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:

这是一个说明事件的工作小提琴:http: //jsfiddle.net/gugahoi/2ZjWP/8/示例:

$(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;
            }
        });
    });
});

回答by user2031802

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

您可以使用 HTML 5 pushstate 更改地址栏中的 URL

window.history.pushstate

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'
  1. https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history
  2. 如何“安全”地使用 window.history.pushState

回答by palindrom

  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)
  1. 将处理程序绑定到jquery 滚动事件
  2. 使用此 jquery 脚本检查锚点当前是否在屏幕上可见。
  3. 使用 pushstate 或 set location(可能会导致跳转)

回答by George Atsev

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).

您可以绑定到 jQuery 滚动事件 ( http://api.jquery.com/scroll/) 并在每次调用回调时,通过检查以下值来检查用户在文档上滚动了多远: .scrollTop ( http ://api.jquery.com/scrollTop/)并通过操作 location.hash 对象(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.

如果在选择锚点后对锚点进行排序,则可以更精确,以便始终设置第一个可见锚点。

回答by artnikpro

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;
        }
    });
});`

回答by Jef

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.

纯 js 版本在研究如何根据屏幕上 HTML 部分元素的位置更新 URL 时,我一直在寻找这个线程,所以我希望这是一个发布这个的好地方。

This function loops over the HTML section elements.

此函数循环遍历 HTML 部分元素。

        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.

收集相对于视口的 Y 滚动位置。

            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

设置代码在两者之间触发的范围。这里当 section 元素的顶部在 -200px 到 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.

仅通过确保 pageData.id 和 location.hash 不匹配来运行一次。这会阻止它用事件淹没您的浏览器。

        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.

我在这个代码块上使用去抖动器和另一个块来设置活动链接。但这只是跟踪 # 锚点的方法。