gpt4 book ai didi

javascript - 如何阻止滚动事件重复发生?

转载 作者:行者123 更新时间:2023-11-29 18:03:31 27 4
gpt4 key购买 nike

请谁能帮助我解决我网站上的事件?问题是,每次滚动事件触发时,它们都会不断发生。导航菜单位于标题下方,但在滚动时始终停留在顶部,但是当我们一直向上滚动时,我希望它返回标题下方。我不知道我在做什么错。这是我的代码

var navigation = document.querySelector("nav");
var borderBottom = navigation.getAttribute("border-bottom");
var currentDistance = (document.documentElement.scrollHeight);

addEventListener ("scroll", function() {

if (currentDistance > "90px") {
navigation.style.position = "fixed";
navigation.style.top = "0";
navigation.style.borderBottom = "3px solid rgb(157,0,53)";
}

else removeEventListener ("scroll", function() {
navigation.style.position = "fixed";
navigation.style.top = "0";
navigation.style.borderBottom = "3px solid rgb(157,0,53)";
}
);
});


当页面加载并且滚动事件被触发时,div也会飞入,这就是我想要的。但是我的问题是,每次触发滚动事件时,该框都会不断飞行而不是停止,即保持REOCCURRING。这是我使用的代码。

var flyInDiv = document.getElementById("flyInDiv");

addEventListener ("scroll", function() {
var programMenu = document.createElement("DIV");

programMenu.className = "programMenu";
programMenu.appendChild(flyInDiv);

document.body.appendChild(programMenu);

programMenu.style.position = "fixed";

});


我网站的网址是agwconitsha.org

非常感谢你们!

最佳答案

我查看了您的代码和您的网站,看来您正在尝试实现以下目标:


粘性导航仅在用户滚动到标题上方时才变为粘性
用户第一次滚动并停留在那里的服务时间列表


TL; DR-我在http://jsfiddle.net/9o7frxp1/4/处做了一个包含此基本行为的jsfiddle。

在上面的小提琴中,我建议使用CSS类来控制导航的粘性和fly div的动画。 JavaScript仅用于根据用户是否滚动以及滚动位置是多少来打开和关闭这些类。

这对于区分JS和CSS的关注点非常有用,允许每种语言各自做的最好,并且这意味着代码更易于维护。

为了进一步说明问题,现在就以您的<nav>为例,以便使这篇文章不会太长。还要查看我上面的jsfiddle链接以了解飞行div的信息-我已在代码中添加了注释,以解释正在发生的事情,但是请告诉我这是否有意义。

因此,我们有一个nav元素:

<nav id="nav">
Nav
</nav>


我们为 <nav>提供了一些样式-一些默认样式,然后只有它们也具有 .is-sticky类时才应用这些样式:

#nav {
width: 100%;
height: 40px;
}

#nav.is-sticky {
position: fixed;
top: 0;
}


在我们的JavaScript中,找到 <nav>

var navigation = document.getElementById('nav');


现在,我们准备一个在用户滚动时将触发的函数。我们尚未添加任何可监听滚动的内容-我们只是准备好该功能。

function addStickyClass() {
// Every time this function fires, we calculate the scroll position
var currentDistance = document.body.scrollTop;

// If we've scrolled 90px down, add the 'is-sticky' class to our nav.
// If not, remove the 'is-sticky' class.
if (currentDistance > 90) {
navigation.className = 'is-sticky';
} else {
navigation.className = '';
}
}


太酷了-我们快要准备好了。最后一件事-让我们确保每次用户滚动时都会触发上述功能。

window.addEventListener('scroll', addStickyClass);


这意味着我们每次用户滚动时都会询问“他们距离窗口顶部90px(或更多)吗?” -如果是的话,那么导航应该是粘性的,如果不是的话,它应该不是。

stekhn是正确的,因为您还没有设法正确实现事件侦听器,这使您的页面行为异常。

但是,在上面的代码示例中,我建议只需要添加一个事件侦听器,而无需删除它。我还建议您使用上面提到的JS和CSS的替代组合,以稍微不同的方式想象这个问题。

在此答案的代码中,我做了一些简化,以更清楚地说明正在发生的事情-您将在我发布的jsfiddle中看到一个更详尽的版本。

但是,即使我的jsfiddle仍然是您网站上的简化版本,因此您需要对其进行调整-试试吧,让我知道您的进展如何。



更新资料

TL; DR:

我实际上意识到对于 #flyInDiv来说,代码可以更简单一些,并且不需要任何布尔值或 if语句。在 http://jsfiddle.net/9o7frxp1/5/上用注释进行解释的小提琴



但是我仍然想在下面解释我最初实现的内容-我认为这是值得知道的:

因此,如果您还记得,我们有一个函数会在用户每次滚动时触发:



function addStickyClass() {
// Every time this function fires, we calculate the scroll position
var currentDistance = document.body.scrollTop;

// If we've scrolled 90px down, add the 'is-sticky' class to our nav.
// If not, remove the 'is-sticky' class.
if (currentDistance > 90) {
navigation.className = 'is-sticky';
} else {
navigation.className = '';
}
}


每次用户滚动时,此函数都会决定是否在元素中添加 .is-sticky类。

说到这-我们还希望我们的代码根据用户何时滚动来决定其他事情-您的 #flyInDiv的显示。也许我们可以将其包含在此代码块中?

#flyInDiv的逻辑是这样的:


用户首次登陆页面时,默认情况下该元素是不可见的,这要归功于CSS
在用户的第一次滚动中,由于添加了附加的CSS类,因此该元素应出现。
在用户访问您页面的其余时间,该元素应保持在原处。我们不再在乎用户是否在滚动。


让我们来看一下代码方面的工作方式。首先,由于CSS,默认情况下该元素是不可见的。我们有 .is-sticky类,用于使元素可见,但是默认情况下,该类不在元素上:



#flyInDiv {
width: 100px;
height: 100px;

/* Positioned hard right */
position: fixed;
right: 0;

/* Translated an extra 100px to the right, sending it out of view */
transform: translateX(100px);
}

#flyInDiv.is-sticky {
/* No translation, so the element should now simply be hard right */
transform: translateX(0);
}


阶段已经准备好了……我们需要一些JavaScript!

让我们回到我们的 addStickyClass()函数-但我将从这些示例中删除与 <nav>相关的其他代码,以使事情更加清楚。

var flyingDiv = document.getElementById("flyInDiv");

function addStickyClass() {
flyingDiv.className = "is-sticky";
}


请记住,每次用户滚动时都会触发该事件(由于我们之前添加了该事件侦听器),那么会发生什么?

用户第一次滚动时,该元素将获得 .is-sticky类。每次用户滚动时,它都会保持设置状态。

碰巧的是,这不会影响您网站的行为,这是我在最近的小提琴中提到的。如果在 #flyInDiv上继续设置此类,这实际上是可以的,因为这仅意味着从用户首次滚动的那一刻起,它就一直保持可见状态。

但是,严格来说,此代码只需运行一次。我们只想在第一个滚动事件之后设置 .is-sticky类。我们不需要每次用户滚动时都进行设置。

在此示例中,我们忽略了它,因为在每次滚动时执行代码 flyingDiv.className = "is-sticky";时,它只会连续覆盖类名。结果:您的 flyingDiv始终具有 .is-sticky类。

但是,在很多情况下,您确实想强制执行某些肯定只在第一次滚动后才发生的事情-例如,对于这个项目,您需要使用 appendChild()添加一个新的,更复杂的元素在第一次滚动后进入DOM,而不是简单地使用CSS使其可见-我们绝对无法摆脱不断重复自身的代码-这意味着我们的元素不断地被添加!

这就是您要执行的操作-让我们为代码提供有关元素是否可见的知识。这样,它可以决定是否需要运行代码。

在滚动时,它可以不断询问:


元素是不可见的吗?


否:这必须是第一卷。使其可见!
是:这不是第一卷。它已经可见。酷,什么都不做。



因此,首先我们需要一个变量来求值。让我们为其命名,并将其默认设置为 false。为什么?因为变量是 flyingDivIsVisible(读为“ flying div是否可见?”),并且在页面上发生任何其他事情之前,正如我们已经提到的,答案应该为“否”。

重要的是,这发生在任何功能之外。我们在这里设置阶段,我们不希望该代码在用户每次滚动时都继续运行。只是在这里为代码提供了我们已经掌握的初步知识-当用户访问页面时,但在滚动之前, #flyInDiv是不可见的。

var flyingDivIsVisible = false;


接下来,我们在函数中添加一些内容。至关重要的是,我们添加的这些新内容位于 if块中,并且仅在 !flyingDivIsVisible为true时运行(或者换句话说,为 flyingDivIsVisible === false):

// Tell our code that the div isn't visible.
var flyingDivIsVisible = false;

function addStickyClass() {

// Only run this code if div isn't visible.
if (!flyingDivIsVisible) {
flyingDiv.className = "is-sticky";

// Tell our code that the div is visible
flyingDivIsVisible = true;
}
}


还记得我们在函数的上方和外部设置了 var flyingDivIsVisible = false;吗?因此,至少在第一次运行此函数时, flyingDivIsVisible === false肯定会评估为true。

但是,只有在 flyingDivIsVisible === false时才运行的东西?好吧,它也恰巧改变了 flyingDivIsVisible = true。为什么?因为运行的东西是将 .is-sticky类添加到 #flyInDiv,这意味着它现在是可见的-但是我们需要通过设置 flyingDivIsVisible = true来向我们的代码提供这些知识。

因此,从现在开始,每滚动一次用户,我们就会有了 flyingDivIsVisible = true,这意味着 if (!flyingDivIsVisible)块中的任何代码都将不再运行。

因此,我们仅实现了一些代码,该代码在用户第一次滚动时运行,但此后再也不会运行。

为了确保尽可能清楚,让我们看一下连续运行两次的函数,然后分解发生的情况。我们还假设我们不断询问代码div是否可见。由于我们已经提供了一种知识的方法,因此它可以不断告诉我们。 PS,在此示例中,我使用了 IIFEs-它们是可以自行运行的函数,而不必等待被单独调用。对于这个示例,我们同步并连续两次运行代码块,这一点更有意义:

// Tell our code the div isn't visible
var flyingDivIsVisible = false;

(function () {
// Us: Is the div visible?
// Code: No. You told it me it isn't.

if (!flyingDivIsVisible) {
flyingDiv.className = "is-sticky";

// Tell our code that the div is visible
flyingDivIsVisible = true;
}
})();

(function () {
// Us: Is the div visible?
// Code: Yes. You told me it was last time I ran this function.

if (!flyingDivIsVisible) {
// Nothing in this block runs, because the div is visible.

flyingDiv.className = "is-sticky";
flyingDivIsVisible = true;
}
})();


顺便说一句,事后想想,如果 #flyInDiv是此代码控制的唯一内容,那么我们也可以在第一次滚动后也删除事件侦听器,以使该代码不再侦听滚动(它不需要,对吗?它已经完成了使div在第一个滚动条上可见的工作。

但是碰巧的是,我们在与 <nav>显示和隐藏相同的代码上下文中想象了这一点,这仍然需要事件侦听器不断询问“用户是否在滚动?”所有时间,所以我们不想删除事件监听器。

希望一切都有道理!

关于javascript - 如何阻止滚动事件重复发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33157822/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com