路口观察器(滚动动画)不工作
Intersection Observer (Scroll Animation) not working
我在观看 Intersection Observer
tutorial 时遇到了这个问题。我的是 div 而不是图像,所以我不必像视频中那样指定属性,我相信我几乎做对了每件事,因为我有 10 个 div,所以我得到了 10 个控制台日志s 带有 class "box",在 JS 文件中用作变量。我使用 opacity 和 transformation 作为动画,如 CSS 中所示。我很感激我做错了什么,我看不到滚动动画的发生。
const targets = document.querySelectorAll('.box');
const lazyLoad = target => {
const io = new IntersectionObserver((entries,observer) => {
entries.forEach(entry => {
console.log('hello World');
if(entry.isIntersecting) {
const div = entry.target;
div.classList.add('fade');
observer.disconnect();
}
});
});
io.observe(target);
};
targets.forEach(lazyLoad);
:root {
--primary-color:#425b84;
--secondary-color:#5b7bb4;
--max-width:1100px;
}
* {
margin:0;
padding:0;
box-sizing:border-box;
}
body {
font:normal 1rem/1.5 'Arial', sans-serif;
background:var(--primary-color);
color:#fff;
overflow-x:hidden;
padding-bottom:50px;
}
#main-header {
background:var(--secondary-color);
padding:4rem 0;
}
.container {
max-width:var(--max-width);
margin:0 auto;
text-align:center;
}
h1 {
font-size:2.3rem;
}
#timeline ul {
background:var(--primary-color);
padding:50px 0;
}
/* Create Line */
#timeline ul li {
list-style:none;
position: relative;
width:6px;
margin:0 auto;
padding-top:50px;
background:#fff;
}
/* Boxes */
#timeline ul li div {
position: relative;
bottom:0;
width:400px;
padding:1rem;
background:var(--secondary-color);
transition:all 0.5s ease-in-out;
opacity:0;
}
.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0);
}
/* Right Side */
#timeline ul li:nth-child(odd) div {
left:40px;
transform:translateX(1100px);
}
/* Left Side */
#timeline ul li:nth-child(even) div {
left:-434px;
transform:translateX(-1100px);
}
/* Dots */
#timeline ul li:after {
content:'';
position: absolute;
left:50%;
bottom:0;
width:25px;
height:25px;
background:var(--secondary-color);
transform:translateX(-50%);
border-radius:50%;
transition:background 0.5s ease-in-out;
}
/* Arrows Base */
#timeline div:before {
content:'';
position: absolute;
bottom:5px;
width:0;
height:0;
border-style:solid;
}
/* Right Side Arrows */
#timeline ul li:nth-child(odd) div:before {
left:-15px;
border-width:8px 16px 8px 0;
border-color:transparent var(--secondary-color) transparent transparent;
}
/* Left Side Arrows */
#timeline ul li:nth-child(even) div:before {
right:-15px;
border-width:8px 0 8px 16px;
border-color:transparent transparent transparent var(--secondary-color);
}
@media(max-width:900px){
#timeline ul li div {
width:250px;
}
#timeline ul li:nth-child(even) div {
left:-284px;
}
}
@media(max-width:600px) {
#timeline ul li {
margin-left:20px;
}
#timeline ul li div {
width:calc(100vw - 90px);
}
#timeline ul li:nth-child(even) div {
left:40px;
}
/* Right Side Arrows */
#timeline ul li:nth-child(even) div:before {
left:-15px;
border-width:8px 16px 8px 0;
border-color:transparent var(--secondary-color) transparent transparent;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://kit.fontawesome.com/bbb16afe05.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./css/aos.css">
<link rel="stylesheet" href="./css/style.css">
<title>Knowledge Timeline</title>
</head>
<body>
<header id="main-header">
<div class="container">
<h1><i class="fas fa-brain"></i> Knowledge Resume</h1>
<h3><div class="fas fa-user"></div> Jun Jung</h3>
</div>
</header>
<section id="timeline">
<ul>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2007: HTML & CSS</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2009: JavaScript & jQuery</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2010: PHP & Wordpress</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2011: Ruby on Rails</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2012: Python</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box"
>
<h3><i class="fas fa-chevron-right"></i> 2013: Node.js & React</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2014: Angular & React Native</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2015: Vue.js </h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2016:GraphQL & Apollo</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2017: Machine Learning</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
</ul>
</section>
<script src="./js/main.js"></script>
</body>
</html>
变换出视线
在您提供的示例中,.box
元素不会相交,因为它们在视口之外。这是由于这些元素上的 transform
属性 将它们置于视图之外。删除 transform
属性将修复它。您可以通过在 .box
元素内添加另一个 div 来解决这个问题,该元素在视图外进行了转换。通过这种方式观察父项 (.box
) 并在视图中,.box
的子项在外部变换并且可以在 .box
相交时动画返回。
淡入淡出
由于 .box
div 的特殊性,.fade
class 无法正常工作。 #timeline ul li div
比 .fade
更具体,因此 .fade
将始终被 #timeline ul li div
的 ID 选择器覆盖。要解决这个问题,要么使用 .box { ... }
和 .box.fade { ... }
使您的选择器不那么具体,要么将 .fade
添加到特定的选择器,如下所示:#timeline ul li div.fade
.
单个实例
此外,避免为每个元素创建 IntersectionObserver
的实例。一个观察者可以观察多个元素。仅当 callback
参数不同时才应创建多个实例。
在您的情况下,所有 .box
元素必须相同处理。
const targets = document.querySelectorAll('.box');
const onObserve = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const div = entry.target;
div.classList.add('fade');
observer.unobserve(div);
}
});
}
const io = new IntersectionObserver(onObserve);
const observeTargets = targets => targets.forEach(target => {
io.observe(target);
});
observeTargets(targets);
:root {
--primary-color: #425b84;
--secondary-color: #5b7bb4;
--max-width: 1100px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font: normal 1rem/1.5 'Arial', sans-serif;
background: var(--primary-color);
color: #fff;
overflow-x: hidden;
padding-bottom: 50px;
}
#main-header {
background: var(--secondary-color);
padding: 4rem 0;
}
.container {
max-width: var(--max-width);
margin: 0 auto;
text-align: center;
}
h1 {
font-size: 2.3rem;
}
#timeline ul {
background: var(--primary-color);
padding: 50px 0;
}
/* Create Line */
#timeline ul li {
list-style: none;
position: relative;
width: 6px;
margin: 0 auto;
padding-top: 50px;
background: #fff;
}
/* Boxes */
#timeline ul li div {
position: relative;
bottom: 0;
width: 400px;
padding: 1rem;
background: var(--secondary-color);
transition: all 0.5s ease-in-out;
opacity: 0;
}
#timeline ul li div.fade {
opacity: 1;
transition: all 0.5s ease-in-out;
transform: translateX(0);
}
/* Right Side */
#timeline ul li:nth-child(odd) div {
left: 40px;
/* transform: translateX(1100px); */
}
/* Left Side */
#timeline ul li:nth-child(even) div {
left: -434px;
/* transform: translateX(-1100px); */
}
/* Dots */
#timeline ul li:after {
content: '';
position: absolute;
left: 50%;
bottom: 0;
width: 25px;
height: 25px;
background: var(--secondary-color);
transform: translateX(-50%);
border-radius: 50%;
transition: background 0.5s ease-in-out;
}
/* Arrows Base */
#timeline div:before {
content: '';
position: absolute;
bottom: 5px;
width: 0;
height: 0;
border-style: solid;
}
/* Right Side Arrows */
#timeline ul li:nth-child(odd) div:before {
left: -15px;
border-width: 8px 16px 8px 0;
border-color: transparent var(--secondary-color) transparent transparent;
}
/* Left Side Arrows */
#timeline ul li:nth-child(even) div:before {
right: -15px;
border-width: 8px 0 8px 16px;
border-color: transparent transparent transparent var(--secondary-color);
}
@media(max-width:900px) {
#timeline ul li div {
width: 250px;
}
#timeline ul li:nth-child(even) div {
left: -284px;
}
}
@media(max-width:600px) {
#timeline ul li {
margin-left: 20px;
}
#timeline ul li div {
width: calc(100vw - 90px);
}
#timeline ul li:nth-child(even) div {
left: 40px;
}
/* Right Side Arrows */
#timeline ul li:nth-child(even) div:before {
left: -15px;
border-width: 8px 16px 8px 0;
border-color: transparent var(--secondary-color) transparent transparent;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://kit.fontawesome.com/bbb16afe05.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./css/aos.css">
<link rel="stylesheet" href="./css/style.css">
<title>Knowledge Timeline</title>
</head>
<body>
<header id="main-header">
<div class="container">
<h1><i class="fas fa-brain"></i> Knowledge Resume</h1>
<h3>
<div class="fas fa-user"></div> Jun Jung</h3>
</div>
</header>
<section id="timeline">
<ul>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2007: HTML & CSS</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2009: JavaScript & jQuery</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2010: PHP & Wordpress</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2011: Ruby on Rails</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2012: Python</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2013: Node.js & React</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2014: Angular & React Native</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2015: Vue.js </h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2016:GraphQL & Apollo</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2017: Machine Learning</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
</ul>
</section>
<script src="./js/main.js"></script>
</body>
</html>
您的路口观察器目前正在瞄准 .box
元素,这些元素会触发最初的 10 个控制台日志,因为它们存在于 DOM 上,但不会在滚动时触发,因为它们不在屏幕上(out视口)。
此外,如其他答案中所述,您应该为所有实例使用一个共同的观察者。
但是,如果你想为每个实例使用一个单独的观察者,你可以将 .box
元素的父元素作为目标,即 <li>
元素,当 <li>
元素滚动到视图,您可以将 class 添加到它的子元素,即您之前使用 ParentNode.children 属性 定位的 .box
元素,如下所示:
const targets = document.querySelectorAll('#timeline li');
const lazyLoad = target => {
const io = new IntersectionObserver((entries,observer) => {
entries.forEach(entry => {
console.log('hello World');
if(entry.isIntersecting) {
const div = entry.target.children[0];
div.classList.add('fade');
observer.disconnect();
}
});
});
io.observe(target);
};
targets.forEach(lazyLoad);
此外,您的 css #timeline ul li:nth-child(odd) div
样式属性正在覆盖您的新 .fade
属性,因为它的定位更加精确。您将需要新的 .fade
属性来定位 .box
元素,就像您对初始样式所做的那样精确:
#timeline ul li:nth-child(odd) div.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0) !important;
}
#timeline ul li:nth-child(even) div.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0) !important;
}
或者你可以像这样组合上面的 css:
#timeline ul li:nth-child(odd) div.fade, #timeline ul li:nth-child(even) div.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0) !important;
}
检查并 运行 以下代码片段或打开此 JSFiddle link 以获得上述的实际示例:
const targets = document.querySelectorAll('#timeline li');
const lazyLoad = target => {
const io = new IntersectionObserver((entries,observer) => {
entries.forEach(entry => {
console.log('hello World');
if(entry.isIntersecting) {
const div = entry.target.children[0];
div.classList.add('fade');
observer.disconnect();
}
});
});
io.observe(target);
};
targets.forEach(lazyLoad);
:root {
--primary-color:#425b84;
--secondary-color:#5b7bb4;
--max-width:1100px;
}
* {
margin:0;
padding:0;
box-sizing:border-box;
}
body {
font:normal 1rem/1.5 'Arial', sans-serif;
background:var(--primary-color);
color:#fff;
overflow-x:hidden;
padding-bottom:50px;
}
#main-header {
background:var(--secondary-color);
padding:4rem 0;
}
.container {
max-width:var(--max-width);
margin:0 auto;
text-align:center;
}
h1 {
font-size:2.3rem;
}
#timeline ul {
background:var(--primary-color);
padding:50px 0;
}
/* Create Line */
#timeline ul li {
list-style:none;
position: relative;
width:6px;
margin:0 auto;
padding-top:50px;
background:#fff;
}
/* Boxes */
#timeline ul li div {
position: relative;
bottom:0;
width:400px;
padding:1rem;
background:var(--secondary-color);
transition:all 0.5s ease-in-out;
opacity:0;
}
#timeline ul li:nth-child(odd) div.fade, #timeline ul li:nth-child(even) div.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0) !important;
}
/* Right Side */
#timeline ul li:nth-child(odd) div {
left:40px;
transform:translateX(1100px);
}
/* Left Side */
#timeline ul li:nth-child(even) div {
left:-434px;
transform:translateX(-1100px);
}
/* Dots */
#timeline ul li:after {
content:'';
position: absolute;
left:50%;
bottom:0;
width:25px;
height:25px;
background:var(--secondary-color);
transform:translateX(-50%);
border-radius:50%;
transition:background 0.5s ease-in-out;
}
/* Arrows Base */
#timeline div:before {
content:'';
position: absolute;
bottom:5px;
width:0;
height:0;
border-style:solid;
}
/* Right Side Arrows */
#timeline ul li:nth-child(odd) div:before {
left:-15px;
border-width:8px 16px 8px 0;
border-color:transparent var(--secondary-color) transparent transparent;
}
/* Left Side Arrows */
#timeline ul li:nth-child(even) div:before {
<header id="main-header">
<div class="container">
<h1><i class="fas fa-brain"></i> Knowledge Resume</h1>
<h3><div class="fas fa-user"></div> Jun Jung</h3>
</div>
</header>
<section id="timeline">
<ul>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2007: HTML & CSS</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2009: JavaScript & jQuery</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2010: PHP & Wordpress</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2011: Ruby on Rails</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2012: Python</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box"
>
<h3><i class="fas fa-chevron-right"></i> 2013: Node.js & React</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2014: Angular & React Native</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2015: Vue.js </h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2016:GraphQL & Apollo</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2017: Machine Learning</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
</ul>
</section>
我在观看 Intersection Observer
tutorial 时遇到了这个问题。我的是 div 而不是图像,所以我不必像视频中那样指定属性,我相信我几乎做对了每件事,因为我有 10 个 div,所以我得到了 10 个控制台日志s 带有 class "box",在 JS 文件中用作变量。我使用 opacity 和 transformation 作为动画,如 CSS 中所示。我很感激我做错了什么,我看不到滚动动画的发生。
const targets = document.querySelectorAll('.box');
const lazyLoad = target => {
const io = new IntersectionObserver((entries,observer) => {
entries.forEach(entry => {
console.log('hello World');
if(entry.isIntersecting) {
const div = entry.target;
div.classList.add('fade');
observer.disconnect();
}
});
});
io.observe(target);
};
targets.forEach(lazyLoad);
:root {
--primary-color:#425b84;
--secondary-color:#5b7bb4;
--max-width:1100px;
}
* {
margin:0;
padding:0;
box-sizing:border-box;
}
body {
font:normal 1rem/1.5 'Arial', sans-serif;
background:var(--primary-color);
color:#fff;
overflow-x:hidden;
padding-bottom:50px;
}
#main-header {
background:var(--secondary-color);
padding:4rem 0;
}
.container {
max-width:var(--max-width);
margin:0 auto;
text-align:center;
}
h1 {
font-size:2.3rem;
}
#timeline ul {
background:var(--primary-color);
padding:50px 0;
}
/* Create Line */
#timeline ul li {
list-style:none;
position: relative;
width:6px;
margin:0 auto;
padding-top:50px;
background:#fff;
}
/* Boxes */
#timeline ul li div {
position: relative;
bottom:0;
width:400px;
padding:1rem;
background:var(--secondary-color);
transition:all 0.5s ease-in-out;
opacity:0;
}
.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0);
}
/* Right Side */
#timeline ul li:nth-child(odd) div {
left:40px;
transform:translateX(1100px);
}
/* Left Side */
#timeline ul li:nth-child(even) div {
left:-434px;
transform:translateX(-1100px);
}
/* Dots */
#timeline ul li:after {
content:'';
position: absolute;
left:50%;
bottom:0;
width:25px;
height:25px;
background:var(--secondary-color);
transform:translateX(-50%);
border-radius:50%;
transition:background 0.5s ease-in-out;
}
/* Arrows Base */
#timeline div:before {
content:'';
position: absolute;
bottom:5px;
width:0;
height:0;
border-style:solid;
}
/* Right Side Arrows */
#timeline ul li:nth-child(odd) div:before {
left:-15px;
border-width:8px 16px 8px 0;
border-color:transparent var(--secondary-color) transparent transparent;
}
/* Left Side Arrows */
#timeline ul li:nth-child(even) div:before {
right:-15px;
border-width:8px 0 8px 16px;
border-color:transparent transparent transparent var(--secondary-color);
}
@media(max-width:900px){
#timeline ul li div {
width:250px;
}
#timeline ul li:nth-child(even) div {
left:-284px;
}
}
@media(max-width:600px) {
#timeline ul li {
margin-left:20px;
}
#timeline ul li div {
width:calc(100vw - 90px);
}
#timeline ul li:nth-child(even) div {
left:40px;
}
/* Right Side Arrows */
#timeline ul li:nth-child(even) div:before {
left:-15px;
border-width:8px 16px 8px 0;
border-color:transparent var(--secondary-color) transparent transparent;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://kit.fontawesome.com/bbb16afe05.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./css/aos.css">
<link rel="stylesheet" href="./css/style.css">
<title>Knowledge Timeline</title>
</head>
<body>
<header id="main-header">
<div class="container">
<h1><i class="fas fa-brain"></i> Knowledge Resume</h1>
<h3><div class="fas fa-user"></div> Jun Jung</h3>
</div>
</header>
<section id="timeline">
<ul>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2007: HTML & CSS</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2009: JavaScript & jQuery</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2010: PHP & Wordpress</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2011: Ruby on Rails</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2012: Python</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box"
>
<h3><i class="fas fa-chevron-right"></i> 2013: Node.js & React</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2014: Angular & React Native</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2015: Vue.js </h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2016:GraphQL & Apollo</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2017: Machine Learning</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
</ul>
</section>
<script src="./js/main.js"></script>
</body>
</html>
变换出视线
在您提供的示例中,.box
元素不会相交,因为它们在视口之外。这是由于这些元素上的 transform
属性 将它们置于视图之外。删除 transform
属性将修复它。您可以通过在 .box
元素内添加另一个 div 来解决这个问题,该元素在视图外进行了转换。通过这种方式观察父项 (.box
) 并在视图中,.box
的子项在外部变换并且可以在 .box
相交时动画返回。
淡入淡出
由于 .box
div 的特殊性,.fade
class 无法正常工作。 #timeline ul li div
比 .fade
更具体,因此 .fade
将始终被 #timeline ul li div
的 ID 选择器覆盖。要解决这个问题,要么使用 .box { ... }
和 .box.fade { ... }
使您的选择器不那么具体,要么将 .fade
添加到特定的选择器,如下所示:#timeline ul li div.fade
.
单个实例
此外,避免为每个元素创建 IntersectionObserver
的实例。一个观察者可以观察多个元素。仅当 callback
参数不同时才应创建多个实例。
在您的情况下,所有 .box
元素必须相同处理。
const targets = document.querySelectorAll('.box');
const onObserve = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const div = entry.target;
div.classList.add('fade');
observer.unobserve(div);
}
});
}
const io = new IntersectionObserver(onObserve);
const observeTargets = targets => targets.forEach(target => {
io.observe(target);
});
observeTargets(targets);
:root {
--primary-color: #425b84;
--secondary-color: #5b7bb4;
--max-width: 1100px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font: normal 1rem/1.5 'Arial', sans-serif;
background: var(--primary-color);
color: #fff;
overflow-x: hidden;
padding-bottom: 50px;
}
#main-header {
background: var(--secondary-color);
padding: 4rem 0;
}
.container {
max-width: var(--max-width);
margin: 0 auto;
text-align: center;
}
h1 {
font-size: 2.3rem;
}
#timeline ul {
background: var(--primary-color);
padding: 50px 0;
}
/* Create Line */
#timeline ul li {
list-style: none;
position: relative;
width: 6px;
margin: 0 auto;
padding-top: 50px;
background: #fff;
}
/* Boxes */
#timeline ul li div {
position: relative;
bottom: 0;
width: 400px;
padding: 1rem;
background: var(--secondary-color);
transition: all 0.5s ease-in-out;
opacity: 0;
}
#timeline ul li div.fade {
opacity: 1;
transition: all 0.5s ease-in-out;
transform: translateX(0);
}
/* Right Side */
#timeline ul li:nth-child(odd) div {
left: 40px;
/* transform: translateX(1100px); */
}
/* Left Side */
#timeline ul li:nth-child(even) div {
left: -434px;
/* transform: translateX(-1100px); */
}
/* Dots */
#timeline ul li:after {
content: '';
position: absolute;
left: 50%;
bottom: 0;
width: 25px;
height: 25px;
background: var(--secondary-color);
transform: translateX(-50%);
border-radius: 50%;
transition: background 0.5s ease-in-out;
}
/* Arrows Base */
#timeline div:before {
content: '';
position: absolute;
bottom: 5px;
width: 0;
height: 0;
border-style: solid;
}
/* Right Side Arrows */
#timeline ul li:nth-child(odd) div:before {
left: -15px;
border-width: 8px 16px 8px 0;
border-color: transparent var(--secondary-color) transparent transparent;
}
/* Left Side Arrows */
#timeline ul li:nth-child(even) div:before {
right: -15px;
border-width: 8px 0 8px 16px;
border-color: transparent transparent transparent var(--secondary-color);
}
@media(max-width:900px) {
#timeline ul li div {
width: 250px;
}
#timeline ul li:nth-child(even) div {
left: -284px;
}
}
@media(max-width:600px) {
#timeline ul li {
margin-left: 20px;
}
#timeline ul li div {
width: calc(100vw - 90px);
}
#timeline ul li:nth-child(even) div {
left: 40px;
}
/* Right Side Arrows */
#timeline ul li:nth-child(even) div:before {
left: -15px;
border-width: 8px 16px 8px 0;
border-color: transparent var(--secondary-color) transparent transparent;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://kit.fontawesome.com/bbb16afe05.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./css/aos.css">
<link rel="stylesheet" href="./css/style.css">
<title>Knowledge Timeline</title>
</head>
<body>
<header id="main-header">
<div class="container">
<h1><i class="fas fa-brain"></i> Knowledge Resume</h1>
<h3>
<div class="fas fa-user"></div> Jun Jung</h3>
</div>
</header>
<section id="timeline">
<ul>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2007: HTML & CSS</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2009: JavaScript & jQuery</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2010: PHP & Wordpress</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2011: Ruby on Rails</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2012: Python</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2013: Node.js & React</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2014: Angular & React Native</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2015: Vue.js </h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2016:GraphQL & Apollo</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2017: Machine Learning</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
</ul>
</section>
<script src="./js/main.js"></script>
</body>
</html>
您的路口观察器目前正在瞄准 .box
元素,这些元素会触发最初的 10 个控制台日志,因为它们存在于 DOM 上,但不会在滚动时触发,因为它们不在屏幕上(out视口)。
此外,如其他答案中所述,您应该为所有实例使用一个共同的观察者。
但是,如果你想为每个实例使用一个单独的观察者,你可以将 .box
元素的父元素作为目标,即 <li>
元素,当 <li>
元素滚动到视图,您可以将 class 添加到它的子元素,即您之前使用 ParentNode.children 属性 定位的 .box
元素,如下所示:
const targets = document.querySelectorAll('#timeline li');
const lazyLoad = target => {
const io = new IntersectionObserver((entries,observer) => {
entries.forEach(entry => {
console.log('hello World');
if(entry.isIntersecting) {
const div = entry.target.children[0];
div.classList.add('fade');
observer.disconnect();
}
});
});
io.observe(target);
};
targets.forEach(lazyLoad);
此外,您的 css #timeline ul li:nth-child(odd) div
样式属性正在覆盖您的新 .fade
属性,因为它的定位更加精确。您将需要新的 .fade
属性来定位 .box
元素,就像您对初始样式所做的那样精确:
#timeline ul li:nth-child(odd) div.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0) !important;
}
#timeline ul li:nth-child(even) div.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0) !important;
}
或者你可以像这样组合上面的 css:
#timeline ul li:nth-child(odd) div.fade, #timeline ul li:nth-child(even) div.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0) !important;
}
检查并 运行 以下代码片段或打开此 JSFiddle link 以获得上述的实际示例:
const targets = document.querySelectorAll('#timeline li');
const lazyLoad = target => {
const io = new IntersectionObserver((entries,observer) => {
entries.forEach(entry => {
console.log('hello World');
if(entry.isIntersecting) {
const div = entry.target.children[0];
div.classList.add('fade');
observer.disconnect();
}
});
});
io.observe(target);
};
targets.forEach(lazyLoad);
:root {
--primary-color:#425b84;
--secondary-color:#5b7bb4;
--max-width:1100px;
}
* {
margin:0;
padding:0;
box-sizing:border-box;
}
body {
font:normal 1rem/1.5 'Arial', sans-serif;
background:var(--primary-color);
color:#fff;
overflow-x:hidden;
padding-bottom:50px;
}
#main-header {
background:var(--secondary-color);
padding:4rem 0;
}
.container {
max-width:var(--max-width);
margin:0 auto;
text-align:center;
}
h1 {
font-size:2.3rem;
}
#timeline ul {
background:var(--primary-color);
padding:50px 0;
}
/* Create Line */
#timeline ul li {
list-style:none;
position: relative;
width:6px;
margin:0 auto;
padding-top:50px;
background:#fff;
}
/* Boxes */
#timeline ul li div {
position: relative;
bottom:0;
width:400px;
padding:1rem;
background:var(--secondary-color);
transition:all 0.5s ease-in-out;
opacity:0;
}
#timeline ul li:nth-child(odd) div.fade, #timeline ul li:nth-child(even) div.fade {
opacity:1;
transition:all 0.5s ease-in-out;
transform:translateX(0) !important;
}
/* Right Side */
#timeline ul li:nth-child(odd) div {
left:40px;
transform:translateX(1100px);
}
/* Left Side */
#timeline ul li:nth-child(even) div {
left:-434px;
transform:translateX(-1100px);
}
/* Dots */
#timeline ul li:after {
content:'';
position: absolute;
left:50%;
bottom:0;
width:25px;
height:25px;
background:var(--secondary-color);
transform:translateX(-50%);
border-radius:50%;
transition:background 0.5s ease-in-out;
}
/* Arrows Base */
#timeline div:before {
content:'';
position: absolute;
bottom:5px;
width:0;
height:0;
border-style:solid;
}
/* Right Side Arrows */
#timeline ul li:nth-child(odd) div:before {
left:-15px;
border-width:8px 16px 8px 0;
border-color:transparent var(--secondary-color) transparent transparent;
}
/* Left Side Arrows */
#timeline ul li:nth-child(even) div:before {
<header id="main-header">
<div class="container">
<h1><i class="fas fa-brain"></i> Knowledge Resume</h1>
<h3><div class="fas fa-user"></div> Jun Jung</h3>
</div>
</header>
<section id="timeline">
<ul>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2007: HTML & CSS</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2009: JavaScript & jQuery</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2010: PHP & Wordpress</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2011: Ruby on Rails</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2012: Python</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box"
>
<h3><i class="fas fa-chevron-right"></i> 2013: Node.js & React</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2014: Angular & React Native</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2015: Vue.js </h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2016:GraphQL & Apollo</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
<li>
<div class="box">
<h3><i class="fas fa-chevron-right"></i> 2017: Machine Learning</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque animi at, dolorum tempora labore exercitationem sapiente voluptate possimus necessitatibus quos cum, voluptatibus maiores voluptates quam illum consequatur nemo est dolores.</p>
</div>
</li>
</ul>
</section>