Javascript 如何检测自动滚动到锚?

Javascript 如何检测自动滚动到锚?,javascript,javascript-events,anchor,hashchange,Javascript,Javascript Events,Anchor,Hashchange,我有一个一页的网站,example.com。有两个部分:页面顶部的简介和页面底部的联系人。如果我希望有人访问联系人部分而不必滚动介绍,我会给他们以下链接:example.com/#contact。我在下面谈论这些访问 浏览器会自动向下滚动到联系人部分,但它会忽略页面顶部的固定导航,因此联系人部分会滚动到导航后面,因此联系人部分的顶部将不可见。这就是我想用JavaScript纠正的,从滚动位置减去固定导航的高度。让我们将此函数称为滚动校正器。问题是我不知道这种自动滚动是什么时候发生的,所以不是每次

我有一个一页的网站,example.com。有两个部分:页面顶部的简介和页面底部的联系人。如果我希望有人访问联系人部分而不必滚动介绍,我会给他们以下链接:example.com/#contact。我在下面谈论这些访问

浏览器会自动向下滚动到联系人部分,但它会忽略页面顶部的固定导航,因此联系人部分会滚动到导航后面,因此联系人部分的顶部将不可见。这就是我想用JavaScript纠正的,从滚动位置减去固定导航的高度。让我们将此函数称为
滚动校正器
。问题是我不知道这种自动滚动是什么时候发生的,所以不是每次都调用
scrollCorrector

什么时候调用
滚动校正器
?当由于哈希部分而发生自动滚动时。为什么不使用
onscroll
?因为这样我无法区分自动滚动和用户滚动。为什么不在每个
上使用
onclick
?我会使用它,但是如果用户通过浏览器的后退按钮导航呢?好的,我也将使用
onpopstate
。但是,如果用户来自example.com/#intro,手动将URL重写为example.com/#contact,该怎么办?好的,我也将使用
onhashchange
。但是,如果用户已经在example.com/#contact上,单击地址栏并按enter键而不做任何修改,该怎么办?以上这些都没有帮助


那我该听什么节目呢?如果这样的事件不存在,那么
scrollCorrector
如何知道刚刚发生了自动滚动?

我已经查看了,是的,我可以看到您使用
window.onhashchange时提到的限制

我知道你想要什么,但我认为这样的事情不存在

这是我想到的最好的(完全放弃hashchange):


“严格使用”;
(功能(){
window.myFunc=函数(href){
window.alert(“点击链接,散列为:“+href”);
};
alert(“刚刚重新加载的页面,散列为:“+window.location.hash”);
})();

A. B
滚动事件将触发,因此您可以

  • 检查您的实际
    位置。散列
    ,如果为空,我们不在乎
  • 确保不是鼠标滚轮触发的事件
  • 获取实际的
    文档.querySelector(location.hash).getBoundingClientRect().top
    ,如果它是
    ==0
    ,则调用您的
    滚动校正器
var-AnchorScroller=function(){
//用于跟踪上次滚动事件的变量
var last=-100,//对于第一个调用(在页面加载时),我们将其设置为-100,并将其理解为锚调用
//一个保持去盎司超时的变量,以便我们可以进一步取消它
超时;
this.debounce=函数(e){
//首先检查我们是否有哈希集,然后检查最后一次调用scroll是否是在100毫秒前发出的
if(location.hash!=''&&performance.now()-last>100)
//如果是这样,请设置一个超时,以确保没有其他滚动出现
超时=设置超时(shouldFire,100);
//那不是锚卷轴,马上停下来!
else clearTimeout(超时);
//设置新的时间戳
last=performance.now();
}
函数shouldFire(){
//指向锚定元素的指针
var el=document.querySelector(window.location.hash);
//如果不为null(location.hash的另一种用法),并且它位于视口的顶部
if(el&&el.getBoundingClientRect().top==0){
//这是一个锚卷轴
scrollTo(0,window.pageYOffset-64);
}
}
};
window.onscroll=新锚定器().debounce
正文{
利润率:64px0;
}
导航{
背景:蓝色;
不透明度:0.7;
位置:固定;
排名:0;
宽度:100%;
}
a{
颜色:#fff;
浮动:左;
字体大小:30px;
高度:64px;
线高:64px;
文本对齐:居中;
文字装饰:无;
宽度:50%;
}
div{
背景:灰色;
边框顶部:5px#0f0虚线;
字体大小:30px;
填充:25VH0;
文本对齐:居中;
}
#简介,#联系人{背景:红色;}

简介
洛勒姆
接触

Ipsum
问题是什么?什么是跳跃?(我可能很愚蠢???)我的意思是,当浏览器滚动到文档中具有与URL哈希部分匹配id的特定元素时。好的,我想我现在明白了,但您的问题非常不清楚,您可能希望更清楚地说明您的问题。没有内置的功能来做你想做的事情,你可以做类似这样的事情,检查当你滚动时锚是否可见。然后,当它“跳转”时,您可以触发自定义事件。这就是你的意思吗?关于只触发一个事件的锚,你可以直接将事件绑定到锚。但不幸的是,当用户在地址栏中按enter键而不做任何更改时,您将很难触发任何类型的事件。我同意,但我不知道如何更清楚地描述问题。我以后可能会重写,但现在已经凌晨2点了,我没有咖啡了。:)无论如何,谢谢你的帮助。我知道如何检查元素是否在视口中。我不知道的是我应该什么时候检查它。我的意思是我知道什么时候检查,但不知道事件是否发生。点击链接可以被检测到。可以检测到哈希更改。但无法检测到导致浏览器再次滚动到指定元素的“哈希更改为相同哈希”。至少我还没弄明白。谢谢,但这只会在重新加载和点击链接时发出警报。尝试在Mozilla Firefox或Microsoft Edge中打开此文件,以便看到
example.com/index.html\b
。滚动至#a,无需单击或重新加载。现在
<html>
<head>
<script>
"use strict";
(function () {
    window.myFunc = function(href) {
        window.alert("Link clicked, hash is: " + href);
    };
    window.alert("Page just reloaded, hash is: " + window.location.hash);
})();
</script>
</head>
<body>
<a href="#a" onclick="myFunc(this.hash)">a</a><br />
<a href="#b" onclick="myFunc(this.hash)">b</a>
<h1 id="a">a</a>
<h1 id="b">b</a>
</body>
</html>