简体   繁体   English

单击锚书签时防止滚动事件

[英]Preventing scroll event when clicking an anchor bookmark

Clicking the anchor bookmark triggers a scroll event. 单击锚书签会触发滚动事件。

How to trigger the callback only when the user scroll happens and not when clicking the bookmark links? 如何仅在用户滚动时而不是在单击书签链接时触发回调?


Note: a poorly worded question with an answer was closed, but I believe it could still be useful to the community because I didn't see a similar question answered on StackOverflow 注意: 一个措辞不佳且有答案的问题已经关闭,但是我认为它对社区仍然有用,因为我在StackOverflow上没有看到类似的问题

Shomz solution relies on the anchor element being in the scrolling context of the document. Shomz解决方案依赖于文档滚动上下文中的锚元素。 If the element is not in the scrolling context of the document the offset check may fail: 如果该元素不在文档的滚动上下文中,则偏移量检查可能会失败:

<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>

I think there are other solutions as well: 我认为还有其他解决方案:

debounce 去抖

Detect when an anchor link was clicked ( hashchange / onclick ) and debounce the scroll event. 检测何时单击了锚链接( hashchange / onclick )并hashchange 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

Depending on why exactly you don't want to trigger your scroll handler when you navigate to an anchor, you could consider attaching it only to the onwheel event. 根据导航到锚点时您到底不想触发滚动处理程序的原因,可以考虑仅将其附加到onwheel事件上。 This means that other means of scrolling (touch, anchors, arrow keys, Page Down , etc.) wont trigger your handler. 这意味着其他滚动方式(触摸,锚点,箭头键, Page Down等)不会触发您的处理程序。

While it's not possible to prevent the actual event from firing (because it's a part of the browser code and it works like that by design), what can be done is to extend your check conditions - in addition to $(window).scrollTop() > 0 that was originally there, you can also check whether there is a hash in the window location, and if there is, check if the scrolled amount is different from the vertical offset of the element referenced by the URL hash. 虽然不可能阻止实际事件的触发(因为它是浏览器代码的一部分,并且按设计的方式工作),但是除了$(window).scrollTop() > 0 (最初位于该位置),您还可以检查窗口位置是否存在哈希,如果存在,则检查滚动量是否与URL哈希所引用元素的垂直偏移量不同。

Something like this: 像这样:

$(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
    }
});

Live code: 实时代码:

 $(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) } }); 
 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;} 
 <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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM