单击锚点书签时阻止滚动事件

时间:2016-02-16 13:07:11

标签: javascript jquery html

单击锚点书签会触发滚动事件。

如何仅在用户滚动发生时触发回调,而不是在单击书签链接时触发回调?

注意: a poorly worded question的答案已经关闭,但我相信它对社区仍然有用,因为我没有在StackOverflow上看到类似的问题

2 个答案:

答案 0 :(得分:2)

Shomz解决方案依赖于文档滚动上下文中的锚元素。如果元素不在文档的滚动上下文中,则偏移检查可能会失败:

<body>
    <div style="max-height: 200px; overflow: auto">
    <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
    <a name="myanchor">anchor</a>
</body>

我认为还有其他解决方案:

<强>去抖

检测点击锚点链接的时间(hashchange / onclick)并对scroll事件进行去抖动。

var debounce = false;
window.addEventListener("hashchange", function () { // also add one for `onclick`
    debounce = true;
    setTimeout(function () {
        debounce = false;
    }, 1);
});
window.addEventListener("scroll", function () {
    if (debounce) {
        return;
    }
    // .. handle scroll
});

<强> onwheel

根据您导航到锚点时不希望触发滚动处理程序的原因,您可以考虑仅将其附加到onwheel事件。这意味着其他滚动方式(触摸,锚点,箭头键, Page Down 等)不会触发您的处理程序。

答案 1 :(得分:0)

虽然无法防止实际事件被触发(因为它是浏览器代码的一部分并且它的设计类似),但可以做的是延长检查条件 - 除了原来在那里的$(window).scrollTop() > 0之外,您还可以检查窗口位置是否有哈希值,如果有,请检查滚动量是否与URL引用的元素的垂直偏移量不同散列。

这样的事情:

$(window).scroll(function(){
    if($(window).scrollTop() > 0 &&            // if it's scrolled and
       (!window.location.hash ||               // if there's no hash or
       $(window.location.hash).offset() &&     // there is, but the scroll is elsewhere
       $(window.location.hash).offset().top != $(window).scrollTop())
   ) {
        alert('scroll');                       // trigger the callback
    }
});

直播代码:

&#13;
&#13;
$(window).scroll(function(){
    if($(window).scrollTop() > 0 && 
       ($('#c:checked').length == 0 || 
         (!window.location.hash ||
         $(window.location.hash).offset() && 
         $(window.location.hash).offset().top != $(window).scrollTop()
         )
       ) 
     ) {
        $('div').addClass('on');
        setTimeout(function(){
          $('div').removeClass('on');
        }, 1000)
    }
});
&#13;
p {margin: 500px 0;}
div {position: fixed; top: 0; right: 0; opacity: 0.1; transition: all .2s linear; padding: 4px 8px}
div.on {opacity: 1; background: #cfc;}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="c" type="checkbox" checked="checked">Prevent scroll callback on link clicks<br>
<a href="#shomz">Link to the anchor below</a>
<p id="shomz">Anchor here</p>
<div>Scroll triggered</div>
&#13;
&#13;
&#13;