I'm new to JS and wanna know right code style or approach to cod Vanilla JS using ES6. To practice this, I'm using ESLint JS code-style of AirBnb and referencing clean-code-javascript repo. However, I cannot sure it is right style for me because I'm newbie. For this reason, I want to ask code review about my simple Vanilla JS.
What I'm doing.
- Activate hover on/off events to 2 elements because it cannot be implemented by CSS now.
- Activate click event to 2 elements for animation.
- Activate no-rebuild event to window to prevent rebuilding of animation.
My files are photo.js
, photo.css
, and photo.html
.
const initializeAnimation = function initializeAnimation() {
const swiperImgs = document.querySelectorAll('.swiper__img');
const swiperTitles = document.querySelectorAll('.swiper__title');
const swiperImgLefts = document.querySelectorAll('.swiper__img__left');
const swiperImgRights = document.querySelectorAll('.swiper__img__right');
const swiperContentsInsides = document.querySelectorAll('.swiper__contents__inside');
const sections = document.querySelectorAll('.section');
const addHoverOnEventToImg = function addHoverOnEventToImg() {
swiperImgs.forEach((swiperImg, index) => swiperImg.addEventListener('mouseenter', () => {
swiperImg.classList.add('hover-up');
swiperTitles[index].classList.add('hover-up');
swiperImgLefts[index].classList.add('hover-hide');
swiperImgRights[index].classList.add('hover-hide');
}));
};
const addHoverOnEventToTItle = function addHoverOnEventToTItle() {
swiperTitles.forEach((swiperTitle, index) => swiperTitle.addEventListener('mouseenter', () => {
swiperTitle.classList.add('hover-up');
swiperImgs[index].classList.add('hover-up');
swiperImgLefts[index].classList.add('hover-hide');
swiperImgRights[index].classList.add('hover-hide');
}));
};
const addHoverOffEventToImg = function addHoverOffEventToImg() {
swiperImgs.forEach((swiperImg, index) => swiperImg.addEventListener('mouseleave', () => {
swiperImg.classList.remove('hover-up');
swiperTitles[index].classList.remove('hover-up');
swiperImgLefts[index].classList.remove('hover-hide');
swiperImgRights[index].classList.remove('hover-hide');
}));
};
const addHoverOffEventToTitle = function addHoverOffEventToTitle() {
swiperTitles.forEach((swiperTitle, index) => swiperTitle.addEventListener('mouseleave', () => {
swiperTitle.classList.remove('hover-up');
swiperImgs[index].classList.remove('hover-up');
swiperImgLefts[index].classList.remove('hover-hide');
swiperImgRights[index].classList.remove('hover-hide');
}));
};
const addClickEventToImg = () => {
swiperImgs.forEach((swiperImg, index) => swiperImg.addEventListener('click', () => {
swiperImgLefts[index].classList.add('left-gone');
swiperImgRights[index].classList.add('right-gone');
swiperTitles[index].classList.add('move-up');
swiperImg.classList.add('move-down');
sections.forEach((section, sectionIndex) => {
if (sectionIndex !== index) {
section.style.display = 'none';
}
});
swiperContentsInsides[index].classList.add('appear');
fullpage_api.destroy();
}));
};
const addNoRebuildEvent = () => {
window.addEventListener('resize', () => {
if (matchMedia('(max-width: 768px)').matches) {
const moveDownElem = document.querySelector('.move-down');
// moveDownElem.classList.remove('move-down');
moveDownElem.classList.add('no-rebuild');
}
});
};
addHoverOnEventToImg();
addHoverOnEventToTItle();
addHoverOffEventToImg();
addHoverOffEventToTitle();
addClickEventToImg();
addNoRebuildEvent();
};
const initializeFullpage = function initializeFullpage() {
new fullpage('#fullpage', {
autoScrolling: true,
licenseKey: '00000000-00000000-00000000-00000000'
});
fullpage_api.setAllowScrolling(true);
};
window.onload = () => {
initializeAnimation();
initializeFullpage();
};
body {
background-color: #031f1c;
transition: background-color 0.5s;
}
.swiper {
height: 100vh;
position: relative;
}
.swiper__img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 40rem;
transition: all 0.5s;
cursor: pointer;
}
.swiper__img__inside {
position: relative;
padding-top: 150%;
}
.swiper__contents__main,
.swiper__img__left,
.swiper__img__right {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
.swiper__contents__main {
z-index: 1;
transition: all 0.5s;
}
.swiper__img__left {
transition: all 0.5s;
}
.swiper__img__right {
transition: all 0.5s;
}
.irene__left { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-irene1.jpg'); }
.irene__right { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-irene2.jpg'); }
.irene__main { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-irene3.jpg'); }
.seulgi__left { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-seulgi1.jpg'); }
.seulgi__right { background-image: url('../images/photo-seulgi2.jpg'); }
.seulgi__main { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-seulgi3.jpg'); }
.wendy__left { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-wendy1.jpg'); }
.wendy__right { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-wendy2.jpg'); }
.wendy__main { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-wendy3.jpg'); }
.yeri__left { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-yeri1.jpg'); }
.yeri__right { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-yeri2.jpg'); }
.yeri__main { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-yeri3.jpg'); }
.joy__left { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-joy1.jpg'); }
.joy__right { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-joy2.jpg'); }
.joy__main { background-image: url('https://raw.githubusercontent.com/baeharam/Redvelvet-Fansite/master/images/photo-joy3.jpg'); }
.swiper__title {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -10%);
transition: all 0.5s;
cursor: pointer;
}
.swiper__title h2 {
font-size: 20rem;
color: white;
font-family: 'Libre Caslon Display', serif;
}
.swiper__contents {
border: 5px solid red;
}
.swiper__contents__inside {
display: none;
}
.swiper__contents__component {
margin-top: 3rem;
position: relative;
width: 80vw;
}
.hover-up { top: 45%; }
.hover-hide { opacity: 0.7; }
.move-up { animation: moveUp 1.5s both 0.5s; }
.left-rotate { transform: rotate(-5deg) translateX(-50%); }
.right-rotate { transform: rotate(5deg) translateX(50%); }
.left-gone { animation: leftGone 1s both; }
.right-gone { animation: rightGone 1s both; }
.move-down { animation: moveDown 1.5s both 0.5s; }
.hide { animation: hide 1s both 0.5s; }
.show {
display: block;
position: absolute;
animation: show 0s both 1s;
}
/* TODO !important가 좋은 해결방법인가? */
.no-rebuild {
animation-duration: 0s !important;
animation-delay: 0s !important;
}
@keyframes leftGone {
from { transform: rotate(-5deg) translateX(-50%); }
to {
transform: rotate(0deg) translateX(-100%);
opacity: 0;
}
}
@keyframes rightGone {
from { transform: rotate(5deg) translateX(50%); }
to {
transform: rotate(0deg) translateX(100%);
opacity: 0;
}
}
@keyframes moveUp {
from { top: 50%; }
to { top: 5%; }
}
@keyframes moveDown {
from {
top: 50%;
transform: translate(-50%, -50%);
}
to {
top: 40%;
transform: translate(-50%, 0%);
width: 80vw;
}
}
@keyframes moveDownMobile {
from {
top: 50%;
transform: translate(-50%, -50%);
}
to {
top: 20%;
transform: translate(-50%, 0%);
width: 80vw;
}
}
@keyframes show {
from { top: 200%; }
to { top: 100%; }
}
@keyframes hide {
from { opacity: 1; }
to { opacity: 0; }
}
/* Media Query */
@media (max-width: 768px) {
.swiper__title h2 {
font-size: 10rem;
}
.move-down {
animation: moveDownMobile 1.5s both 0.5s;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="https://raw.githack.com/baeharam/Redvelvet-Fansite/master/html/">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://fonts.googleapis.com/css?family=Libre+Caslon+Display&display=swap" rel="stylesheet">
<link rel="stylesheet" href="../css/fullpage.min.css">
<link rel="stylesheet" href="../css/default.css">
<title>Photo</title>
</head>
<body>
<header id="header-js" class="header">
<div class="header__inside clearfix">
<a href="./index.html">
<img class="header__logo" src="../images/logo-red.png" alt="로고">
</a>
<div id="header__menu-js" class="header__menu">
<input type="checkbox" id="menuicon">
<label for="menuicon">
<span class="menu-light"></span>
<span class="menu-light"></span>
<span class="menu-light"></span>
</label>
</div>
</div>
<h1>홈</h1>
</header>
<aside id="overlay-js" class="overlay">
<a href="javascript:void(0)" id="overlay__closeBtn-js" class="overlay__closeBtn">×</a>
<nav class="overlay-menu">
<ul>
<li><a href="./about.html">ABOUT</a></li>
<li><a href="./photo.html">PHOTOS</a></li>
<li><a href="./discography.html">DISCOGRAPHY</a></li>
<li><a href="./video.html">VIDEOS</a></li>
</ul>
</nav>
</aside>
<main id="fullpage">
<section id="irene" class="section">
<div class="swiper">
<div class="swiper__img" data-color="#031F1C">
<div class="swiper__img__inside">
<div class="swiper__img__left irene__left"></div>
<div class="swiper__img__right irene__right"></div>
<div class="swiper__contents">
<div class="swiper__contents__main irene__main"></div>
<div class="swiper__contents__inside">
<img class="swiper__contents__component" src="../images/photo-irene4.jpg" alt="아이린">
<img class="swiper__contents__component" src="../images/photo-irene5.jpg" alt="아이린">
<img class="swiper__contents__component" src="../images/photo-irene6.jpg" alt="아이린">
<img class="swiper__contents__component" src="../images/photo-irene7.jpg" alt="아이린">
</div>
</div>
</div>
</div>
<div class="swiper__title">
<h2>IRENE</h2>
</div>
</div>
</section>
<section id="seulgi" class="section">
<div class="swiper">
<div class="swiper__img" data-color="#1f1b11">
<div class="swiper__img__inside">
<div class="swiper__img__left seulgi__left"></div>
<div class="swiper__img__right seulgi__right"></div>
<div class="swiper__contents">
<div class="swiper__contents__main seulgi__main"></div>
<div class="swiper__contents__inside">
<img class="swiper__contents__component" src="../images/photo-seulgi4.jpg" alt="슬기">
<img class="swiper__contents__component" src="../images/photo-seulgi5.jpg" alt="슬기">
<img class="swiper__contents__component" src="../images/photo-seulgi6.jpg" alt="슬기">
<img class="swiper__contents__component" src="../images/photo-seulgi7.jpg" alt="슬기">
</div>
</div>
</div>
</div>
<div class="swiper__title">
<h2>SEULGI</h2>
</div>
</div>
</section>
<section id="wendy" class="section">
<div class="swiper">
<div class="swiper__img" data-color="#291310">
<div class="swiper__img__inside">
<div class="swiper__img__left wendy__left"></div>
<div class="swiper__img__right wendy__right"></div>
<div class="swiper__contents">
<div class="swiper__contents__main wendy__main"></div>
<div class="swiper__contents__inside">
<img class="swiper__contents__component" src="../images/photo-wendy4.jpg" alt="웬디">
<img class="swiper__contents__component" src="../images/photo-wendy5.jpg" alt="웬디">
<img class="swiper__contents__component" src="../images/photo-wendy6.jpg" alt="웬디">
<img class="swiper__contents__component" src="../images/photo-wendy7.jpg" alt="웬디">
</div>
</div>
</div>
</div>
<div class="swiper__title">
<h2>WENDY</h2>
</div>
</div>
</section>
<section id="yeri" class="section">
<div class="swiper">
<div class="swiper__img" data-color="#5e0238">
<div class="swiper__img__inside">
<div class="swiper__img__left yeri__left"></div>
<div class="swiper__img__right yeri__right"></div>
<div class="swiper__contents">
<div class="swiper__contents__main yeri__main"></div>
<div class="swiper__contents__inside">
<img class="swiper__contents__component" src="../images/photo-yeri4.jpg" alt="예리">
<img class="swiper__contents__component" src="../images/photo-yeri5.jpg" alt="예리">
<img class="swiper__contents__component" src="../images/photo-yeri6.jpg" alt="예리">
<img class="swiper__contents__component" src="../images/photo-yeri7.jpg" alt="예리">
</div>
</div>
</div>
</div>
<div class="swiper__title">
<h2>YERI</h2>
</div>
</div>
</section>
<section id="joy" class="section">
<div class="swiper">
<div class="swiper__img" data-color="#4e087c">
<div class="swiper__img__inside">
<div class="swiper__img__left joy__left"></div>
<div class="swiper__img__right joy__right"></div>
<div class="swiper__contents">
<div class="swiper__contents__main joy__main"></div>
<div class="swiper__contents__inside">
<img class="swiper__contents__component" src="../images/photo-joy4.jpg" alt="조이">
<img class="swiper__contents__component" src="../images/photo-joy5.jpg" alt="조이">
<img class="swiper__contents__component" src="../images/photo-joy6.jpg" alt="조이">
<img class="swiper__contents__component" src="../images/photo-joy7.jpg" alt="조이">
</div>
</div>
</div>
</div>
<div class="swiper__title">
<h2>JOY</h2>
</div>
</div>
</section>
</main>
<script src="../js/fullpage.min.js"></script>
<script src="../js/intersection-observer.js"></script>
<script src="../js/default.js"></script>
<script>
</script>
</body>
</html>
fullpage.min.js
. It is package. \$\endgroup\$