【问题标题】:Prevent default behavior when setting location.hash设置 location.hash 时防止默认行为
【发布时间】:2020-11-22 01:18:33
【问题描述】:

当我这样做时,

location.hash = "test"

url 被更新,页面位于具有该 id 的元素上。

有没有办法阻止页面返回到该元素?

【问题讨论】:

  • location.hash 与 jQuery 无关,它是 JavaScript 的一部分。 jQuery 是 JavaScript 框架。
  • 如果您不想要那种效果,为什么要更改location.hash
  • @Tadeck 我正在这个框架下工作。解决方案是纯 JS 还是 jQuery 对我来说真的没关系,只要它有效。
  • @Zirak 用于标签历史。它工作正常。出于审美原因,我只是不想专注于元素。

标签: javascript


【解决方案1】:

解决方案

你无法阻止这种行为,但你可以通过暂时隐藏目标来欺骗它,例如。像那样(它与jQuery无关):

// obtain "target" DOM (not jQuery) element and do this:
var original_id = target.id; // save original ID
target.id = null; // set target's ID
location.hash = 'test'; // issue location.hash change
target.id = original_id; // set ID to original value

广义解

或更一般的例子:

// make target_hash set to a hash you want to not lead you to page section and:
var element = document.getElementById(target_hash); // find element by ID
var original_id = element.id; // save original ID
location.hash = target_hash; // previously defined by you (eg. 'test')
element.id = original_id; // reset ID

演示/证明

现场示例可以如下,在通过jQuery附加的事件处理程序中(这里演示:http://jsfiddle.net/DaZfH/):

some_link.on('click', function(event){
    event.preventDefault();
    var target = document.getElementById('target');
    var original_id = target.id;
    target.id = null; // unset ID
    location.hash = 'target';
    target.id = original_id;
});

免责声明

但确实其他人是对的:将您移动到文档中的正确位置是正确的行为。如果您正在做我提到的事情,那么您的解决方案就很不自然,而且肯定有更好的方法来做到这一点。

【讨论】:

    【解决方案2】:

    有没有办法阻止页面返回到该元素

    是的。虽然 hashchange 事件是不可取消的,但是你可以像这样重置它不需要的行为。

    var popY,
        popX;
    
    //When location.hash is changed, popstate is the first event to fire 
    //Use this event to record current state
    
    window.addEventListener('popstate', popstateHandler);
    function popstateHandler() {
      popY = window.scrollY;
      popX = window.scrollX;
    }
    
    //Reset scroll position with recorded values when hashchange fires (after page is scrolled)
    
    window.addEventListener('hashchange', hashchangeHandler);
    function hashchangeHandler() {
      window.scrollTo(popX, popY);
    }

    这是它的基础。您可能想为 IE 做一些校对,并实现您这样做的原因:动画滚动、激活某些东西等。

    scrollY、scrollX 的 Polyfill:

    if(!('scrollY' in window)) {
        Object.defineProperty(window, 'scrollY', {
            get: function () {
                return window.pageYOffset
            }
        });
        Object.defineProperty(window, 'scrollX', {
            get: function () {
                return window.pageXOffset
            }
        })
    }

    【讨论】: