代码之家  ›  专栏  ›  技术社区  ›  punkish

location.hash使用链接的新哈希值更新,该哈希值在*单击后被替换

  •  1
  • punkish  · 技术社区  · 5 年前

    有奇怪的JavaScript-“HTML锚散列”-“位置散列”交互发生,我无法理解。来了

    <div id="link"><a href="#foo">switch to foo</a></div>
    
    <script>
        const link = document.querySelector('#link > a');
    
        link.addEventListener('click', function(event) {
            toggleFooBar(this.hash.substr(1));
        });
    
        toggleFooBar = function(type) {
    
            if (type === 'foo') {
                link.hash = '#bar';
                link.innerHTML = 'switch to bar';
            }
            else if (type === 'bar') {
                link.hash = '#foo';
                link.innerHTML = 'switch to foo';
            }
    
        };
    </script>
    

    在页面加载时,链接显示 切换到foo 如预期。当我单击链接时,文本将更改为 切换到条 但是 这个 location.hash 更改为 #bar . 我以为只有 link.hash 在HTML中将更改为 #酒吧 位置.hash 将显示 #foo 因为我一开始就是这么点击的。好像是 链接.hash 以及 位置.hash 链接以便更改 链接.hash 即使 之后 单击已发生更新 位置.hash . 显然,这不是我想要的。我想要 位置.hash 显示 链接.hash 存在于当时的价值 click . 然后,我想要 链接.hash 若要更改为新值,以便再次单击,则可以正确切换回。

    我的错误来源是什么?我该如何纠正它?

    1 回复  |  直到 5 年前
        1
  •  2
  •   Felix Kling    5 年前

    我的错误来源是什么?我该如何纠正它?

    我相信click事件处理程序已执行 之前 事件的默认操作(*)发生。这意味着您实际上是在更新URL之前更新hash abe。

    问题演示:

    const link = document.querySelector('#link > a');
    
    link.addEventListener('click', function(event) {
      toggleFooBar(this.hash.substr(1));
    });
    
    toggleFooBar = function(type) {
    
      if (type === 'foo') {
        link.hash = '#bar';
        link.innerHTML = 'switch to bar';
      } else if (type === 'bar') {
        link.hash = '#foo';
        link.innerHTML = 'switch to foo';
      }
    
      // Only used to show current hash since code is run in an iframe
      setTimeout(() => console.log(window.location.hash), 100);
    };
    <div id="link"><a href="#foo">switch to foo</a></div>

    一个简单的解决方案是通过使用 setTimeout :

    const link = document.querySelector('#link > a');
    
    link.addEventListener('click', function(event) {
      toggleFooBar(this.hash.substr(1));
    });
    
    toggleFooBar = function(type) {
    
      setTimeout(() => {
        if (type === 'foo') {
          link.hash = '#bar';
          link.innerHTML = 'switch to bar';
        } else if (type === 'bar') {
          link.hash = '#foo';
          link.innerHTML = 'switch to foo';
        }
      }, 0);
    
      // Only used to show current hash since code is run in an iframe
      setTimeout(() => console.log(window.location.hash), 100);
    };
    <div id=“link”><a href=“#foo”>切换到foo</a></div>

    *:显然,“默认操作”是一个遗留术语。最新的规范使用了术语“激活行为”。有关详细信息,请访问 https://dom.spec.whatwg.org/#dispatching-events