【问题标题】:Prevent hash change from scrolling防止哈希更改滚动
【发布时间】:2013-03-31 08:21:10
【问题描述】:

对不起,下面的丑陋布局示例... http://www.wthdesign.net/test/test2.html

我设法将我的 id 名称附加到 url:

function generateUrl(el)
{
    var currentId = $(el).attr('id');
    document.location.hash = currentId;
}

并添加:

<a id="abc2" onClick="generateUrl(this)" >this is an anchor btn</a>

但这最终会产生与以下相同的效果:

<a id="abc2" href="#abc2" >this is an anchor btn</a>

一切都很好,但是当我点击链接时我不希望它滚动 我该怎么做?非常感谢。

【问题讨论】:

标签: javascript hyperlink scroll anchor


【解决方案1】:

如果不需要 id,只需 href="#some-value 即可更改窗口位置而不滚动页面。如果您确实需要文档中的id(在本例中为 a 标签),则位置更改将导致滚动。您可以通过在现代浏览器中使用 history 对象或将滚动位置存储在链接单击上,然后使用 hashchange 事件重置它来解决此问题。

我将在这两种解决方案中使用这个标记:

示例标记:

<div class="filler"></div>
<a id="abc1" href="#abc1" class="my-class">this is an anchor btn</a>
<div class="filler"></div>
<a id="abc2" href="#abc2" class="my-class">this is an anchor btn</a>
<div class="filler"></div>
<a id="abc3" href="#abc3" class="my-class">this is an anchor btn</a>
<div class="filler"></div>

history.replaceState 或 history.pushState

Live demo (click).

//get element referneces
var elems = document.getElementsByClassName('my-class');

//iterate over the references
for (var i=0; i<elems.length; ++i) {
  //add click function to each element
  elems[i].addEventListener('click', clickFunc);
}

//this will store the scroll position
var keepScroll = false;

//fires when a ".my-class" link is clicked
function clickFunc(e) {
  //prevent default behavior of the link
  e.preventDefault();
  //add hash
  history.replaceState({}, '', e.target.href);
}

scrollTop 和 hashchange 事件

Live demo (click).

JavaScript:

//get element referneces
var elems = document.getElementsByClassName('my-class');

//iterate over the references
for (var i=0; i<elems.length; ++i) {
  //add click function to each element
  elems[i].addEventListener('click', clickFunc);
}

//this will store the scroll position
var keepScroll = false;

//fires when a ".my-class" link is clicked
function clickFunc(e) {
  //if the location hash is already set to this link
  if (window.location.hash === '#'+e.target.id) {
    //do nothing
    e.preventDefault(); 
  }
  else {
    //the location will change - so store the scroll position
    keepScroll = document.body.scrollTop;
  }
}

window.addEventListener('hashchange', function(e) {
  //the location has has changed

  //if "keepScroll has been set
  if (keepScroll !== false) {
    //move scroll position to stored position
    document.body.scrollTop = keepScroll;
    //set "keepScroll" to false so that this behavior won't affect irrelevant links
    keepScroll = false;
  }
});

【讨论】:

    【解决方案2】:

    我遇到的问题是我使用平滑滚动行为,并且在单击锚链接时 firefox 滚动位置会跳来跳去。所以这里的堆栈溢出没有什么效果很好。如果有人对我最近的方法感兴趣:

    1. 将当前滚动位置存储在滚动监听器中
    2. 创建一个 hashchange 监听器
    3. 通过向 body 添加 css 来防止滚动,利用 window.scroll 功能并立即从 body 中删除 css 以启用滚动

    这是一个例子:

    document.addEventListener('DOMContentLoaded', () => {
    
      // store scroll position
      let scrollTop = document.documentElement.scrollTop
      window.addEventListener('scroll', () => scrollTop = document.documentElement.scrollTop)
    
      window.addEventListener('hashchange', () => {
        // disable scrolling
        document.body.style.overflow = 'hidden'
    
        // set current scroll position
        window.scroll(0, scrollTop)
    
        // enable scrolling
        setTimeout(() => {
          document.body.style.overflow = 'auto'
        }, 10)
      }, false)
    
      // trigger hashchange event on page load
      window.dispatchEvent(new Event('hashchange'))
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多