Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
位置:粘性-与javascript高度调整组合时滚动反弹_Javascript_Html_Css_Navigation_Sticky - Fatal编程技术网

位置:粘性-与javascript高度调整组合时滚动反弹

位置:粘性-与javascript高度调整组合时滚动反弹,javascript,html,css,navigation,sticky,Javascript,Html,Css,Navigation,Sticky,在玩了一会儿position:sticky之后,我开始为sticky导航实现它,并遇到了这个有趣但令人沮丧的滚动反弹问题 这是许多站点上常见的一种导航行为,在这些站点中,您通常使用javascript计算页面中相对元素的偏移量。当元素到达窗口顶部时,将添加一个“卡住”类,使用位置:fixed将元素从文档流中取出,并在其位置添加一个相同高度的虚拟元素,以防止页面“跳跃”。此外,常见的情况是javascript会在滚动时缩小导航的高度以节省空间 CSS现在似乎通过position:sticky解决了

在玩了一会儿
position:sticky
之后,我开始为sticky导航实现它,并遇到了这个有趣但令人沮丧的滚动反弹问题

这是许多站点上常见的一种导航行为,在这些站点中,您通常使用javascript计算页面中相对元素的偏移量。当元素到达窗口顶部时,将添加一个“卡住”类,使用
位置:fixed
将元素从文档流中取出,并在其位置添加一个相同高度的虚拟元素,以防止页面“跳跃”。此外,常见的情况是javascript会在滚动时缩小导航的高度以节省空间

CSS现在似乎通过
position:sticky
解决了所有这些问题,除了(据我所知)检测元素何时“卡住”之外。相反,我使用了一些javascript来进行卡住检测,发现一切都很好,直到粘滞元素的高度需要改变

这很难解释,但它会对生产造成严重破坏——所以我举了一个简单的例子来尽可能简单地说明这个问题

当页面的高度正好是正确的长度时,这是最好的说明,因此我在元素上设置了一个固定的高度,以确保每个人都能看到相同的东西。你可以添加更多的内容,但滚动过去仍然是个问题

结果是一些非常奇怪的行为。向下滚动时,导航条会粘住,当导航条收缩时,浏览器自动创建的“虚拟元素”位置:
position:sticky
似乎与导航条保持同步。这意味着,当添加卡住的类时,整个页面会变小,几秒钟后,导航不再卡住,从而导致一个故障振动循环

我测试过的每个浏览器的行为也完全不同。在chrome中,这种反弹永远无法解决,它停留在无限循环中,不断添加/删除卡住的类。更有趣的是,在Safari中,滚动位置被“向后推”到一个不会出现错误的状态。然后在Firefox中,它会同时执行这两项操作,在再次强制滚动位置之前,会出现一两秒钟的故障

我想知道是否有人经历过这种情况,并提出了解决方案?我提出的任何js解决方案都没有真正起作用,也不是很好!当然,随着人气的增长,越来越多的人会喜欢上这个

天才解决方案,黑客,见解,或完美的解决方案都欢迎

这里是我想出的一个解决方法,它在视觉上提供了相同的效果

似乎转换
变换
而不是
高度
以及
位置:粘性
效果很好。您无法切换常量类

因此,如果我们想将导航高度减半,我们可以通过将
scaleY
从1更改为0.5,将导航高度减半

这反过来会挤压我们的链接,因此我们将这些链接放大一倍,以抵消挤压,将
scaleY
从1调整为2

我们要做的最后一个修复是将导航向上平移到页面顶部,以补偿较小的高度

下面是这个片段。这里的关键部分如下:

nav {
  transform: scaleY(1) translateY(0);
}
nav a {
  transform: scaleY(1);
}
nav.stuck {
  transform: scaleY(0.5) translateY(-50%);
}
nav.stuck a {
  transform: scaleY(2);
}
nav, nav a {
  transition: all 0.6 ease-in-out;
}
前两条规则并不是绝对必要的,但我喜欢在前面和后面加上一条规则,以便让事情更加清楚

nav=document.querySelector('nav');
section=document.querySelector(“section”);
函数supportSticky(){
if(window.CSS&&CSS.supports){
返回CSS.supports(“(位置:粘性)”)| | CSS.supports((位置:-webkit粘性)”);
}否则{
var el=document.createElement(“div”);
el.style.position=“粘性”;
返回el.style.position==“粘性”;
}
}
函数handleScroll(){
函数isStuck(el){
return el.offsetTop-section.scrollTop(显然你需要更多的声誉来评论而不是回答…)

这似乎是一个合法的布局错误,因此我很好奇浏览器贡献者的意见。在Chromium和Firefox错误跟踪程序中提出了问题,以了解会发生什么:


在尝试相同的操作后,我可以确认这是一个问题。我正在使用标题上的position Stick,同时通过JS添加一个类(触发一些动画,这些动画会像上面描述的代码笔那样改变高度)

高度更改实际上会弄乱窗口高度,当它变小1px时,将触发删除动画的else。删除动画会将高度更改回原始大小,循环再次开始


我想知道如何正确地编写此代码,而不让本机
元素/类/伪元素卡住尝试在应用可能改变其大小(并可能影响窗口大小/元素定位)的更改时向粘滞元素添加
溢出锚定:无;

更新:最终,我找到的正确解决方案是:拥有一个永远不会改变大小的外部元素(在任何给定的断点处,它的全高总是相同的)。这个元素是粘性的。但是它也应该没有背景/视觉样式,它的有效高度应该由高度+底边距定义(这样它在文档中占据了适当的初始空间,但在视觉导航缩小并提供更多空间后,实际上不会阻止单击

然后有一个内部元素,它可以改变大小,无论是在现实中还是在视觉上


您还可以使用现代属性,如contain:layout size;在内部元素(如

Nice)上,我没有想到这一点,谢谢。不过,在示例的简单上下文之外,这会变得非常混乱。要使用复杂的导航结构进行任何控制,都将开始
var header = document.getElementById("header");
var sticky = header.offsetTop;

window.onscroll = function () {
    if (window.scrollY > sticky) {
        header.classList.add("stuck");
    } else {
        header.classList.remove("stuck");
    }
};