30

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

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

4

6 回答 6

39

尝试使用这个 jquery 插件:Scrollorama。它有很多很酷的功能,你可以用它window.location.hash来更新你的浏览器哈希。

或者,您可以添加“滚动”事件来检查到达锚点的时间。

这是一个说明事件的工作小提琴: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;
            }
        });
    });
});
于 2013-02-02T09:56:40.560 回答
3

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

window.history.pushstate


  1. https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history
  2. 如何“安全地”使用 window.history.pushState
于 2013-02-02T09:45:52.533 回答
2
  1. 将处理程序绑定到jquery 滚动事件
  2. 使用此 jquery 脚本检查当前是否在屏幕上可见锚点。
  3. 使用 pushstate 或设置位置(可能会导致跳转)
于 2013-02-02T09:52:10.370 回答
2

您可以绑定到 jQuery 滚动事件 ( http://api.jquery.com/scroll/ ) 并在每次调用回调时,通过检查以下值来检查用户在文档上滚动了多远: .scrollTop ( http ://api.jquery.com/scrollTop/)并通过操作 te location.hash 对象(http://www.w3schools.com/jsref/prop_loc_hash.asp)设置锚点。

它会是这样的:

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

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

于 2013-02-02T09:58:03.227 回答
2

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

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

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

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

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

将两个数组转换为一个对象

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

设置代码在两者之间触发的范围。这里会在 section 元素的顶部在 -200px 到 400px 之间时触发

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

通过确保 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);

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

于 2019-09-27T20:27:03.687 回答
1

我认为你需要做这样的事情。未在行动中尝试过

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;
        }
    });
});
于 2013-02-02T10:02:22.777 回答