使用 Intersection Observer 制作动画
Animating with Intersection Observer
我一直在尝试在页面元素出现时为它们设置动画。我必须承认我是一个 Javascript 初学者,我在互联网上找到的所有代码片段也没有用。我的代码究竟有什么问题?
编辑:我只是注意到我的代码在将它作为片段添加到此处时正在运行。我正在使用 chrome 上的 index.html 文件,我的样式表绝对链接正确。我找不到问题所在。为什么它在这里工作而不是在我的浏览器上?是不是因为我忘记添加堆栈溢出代码运行器自动添加的东西?
const options = {
root: null,
rootMargin: '0px',
threshold: 0.5
}
let callback = (entries) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
entry.target.classList.add('isVisible');
} else {
entry.target.classList.remove('isVisible');
}
});
}
let observer = new IntersectionObserver(callback, options);
document.querySelectorAll('.box')
.forEach(box => { observer.observe(box) });
section {
width: 100%;
height: 500px;
padding: 50px;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
div {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
width: 80%;
height: 80%;
}
.box {
opacity: 0;
transform: translateY(40px);
transition: all 1s ease-in-out;
}
.box.isVisible {
opacity: 1;
transform: translateY(0);
}
<!-- ... -->
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<!-- ... -->
因此,根据您提供的更多信息,相同代码无法在您的计算机上运行的原因是 <script>
标记的位置。当放在文档的 <head>
中时,脚本中的代码会在 DOM 准备就绪之前直接执行:这意味着你所有的选择器都会在运行时 return undefined
.
同时,在 Whosebug 上使用的代码片段中,您粘贴的任何 JS 都被注入到 <body>
元素的末尾(这暗示了一种可能的解决方案,请参见下文)。
有两种方法可以解决这个问题:
- 将
<script>
标记移动到 <body>
元素的末尾。这样,当 JS 被评估时,DOM 已经被解析并准备就绪。
- 将所有 JS 逻辑包装在
DOMContentLoaded
event 触发后调用的函数中
我一直在尝试在页面元素出现时为它们设置动画。我必须承认我是一个 Javascript 初学者,我在互联网上找到的所有代码片段也没有用。我的代码究竟有什么问题?
编辑:我只是注意到我的代码在将它作为片段添加到此处时正在运行。我正在使用 chrome 上的 index.html 文件,我的样式表绝对链接正确。我找不到问题所在。为什么它在这里工作而不是在我的浏览器上?是不是因为我忘记添加堆栈溢出代码运行器自动添加的东西?
const options = {
root: null,
rootMargin: '0px',
threshold: 0.5
}
let callback = (entries) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
entry.target.classList.add('isVisible');
} else {
entry.target.classList.remove('isVisible');
}
});
}
let observer = new IntersectionObserver(callback, options);
document.querySelectorAll('.box')
.forEach(box => { observer.observe(box) });
section {
width: 100%;
height: 500px;
padding: 50px;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
div {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
width: 80%;
height: 80%;
}
.box {
opacity: 0;
transform: translateY(40px);
transition: all 1s ease-in-out;
}
.box.isVisible {
opacity: 1;
transform: translateY(0);
}
<!-- ... -->
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<section>
<div class="box">
<h2>
Lorem ipsum dolor sit amed
</h2>
</div>
</section>
<!-- ... -->
因此,根据您提供的更多信息,相同代码无法在您的计算机上运行的原因是 <script>
标记的位置。当放在文档的 <head>
中时,脚本中的代码会在 DOM 准备就绪之前直接执行:这意味着你所有的选择器都会在运行时 return undefined
.
同时,在 Whosebug 上使用的代码片段中,您粘贴的任何 JS 都被注入到 <body>
元素的末尾(这暗示了一种可能的解决方案,请参见下文)。
有两种方法可以解决这个问题:
- 将
<script>
标记移动到<body>
元素的末尾。这样,当 JS 被评估时,DOM 已经被解析并准备就绪。 - 将所有 JS 逻辑包装在
DOMContentLoaded
event 触发后调用的函数中