jQuery : 세로 메뉴 만들기, slide animation, mousewheel 이벤트
2022.12.21.
- UI/UX 반응형 웹디자인&웹퍼블리셔 개발자 과정 - DAY 69
Review
- UI/UX 반응형 웹디자인&웹퍼블리셔 개발자 과정 - DAY 69
<세로 메뉴 만드는 6가지 방법>
- HTML
<ul id="navi">
<li>
<div class="title">title</div>
<ul class="sub">
<li><a href="#">sub11</a></li>
<li><a href="#">sub12</a></li>
<li><a href="#">sub13</a></li>
</ul>
</li>
<li>
<div class="title">title</div>
<ul class="sub">
<li><a href="#">sub21</a></li>
<li><a href="#">sub22</a></li>
<li><a href="#">sub23</a></li>
</ul>
</li>
<li>
<div class="title">title</div>
<ul class="sub">
<li><a href="#">sub31</a></li>
<li><a href="#">sub32</a></li>
<li><a href="#">sub33</a></li>
</ul>
</li>
</ul>
- CSS
@font-face {
font-family: pretendard;
src: url(../fontawesome-free-6.2.0-web/webfonts/Pretendard-Regular.woff)
format("woff");
}
* {
padding: 0;
margin: 0;
font: 1em pretendard, Arial, 돋움, Doctum, sans-serif;
}
ul,
li {
list-style: none;
}
a {
text-decoration: none;
color: #333;
}
body {
color: #333;
}
ul#navi {
width: 200px;
margin: 0 auto;
text-indent: 10px;
/* 들여쓰기 속성 / 음수일 경우는 내어쓰기 */
}
div.title {
height: 35px; /* height 값이 있으면 수직의 가운데로 보낼 수가 없음. line-height만 가능 */
line-height: 35px;
cursor: pointer;
background: rgb(154, 201, 125);
}
#navi > li {
margin-bottom: 3px;
}
div.title.on {
background: #ddd36b;
}
.sub li {
height: 35px;
background: #f4f4f4;
cursor: pointer;
}
.sub li a {
display: block;
width: 100%;
line-height: 35px;
}
.sub li a:hover {
background: #ccc;
}
-jQuery
$(function () {
// step 1
/* $(".sub").hide();
// $(".sub").css("display", "none");
$(".title").click(function () {
$(".sub").hide();
$(this).next().show();
// $(".this").next().css("display", "block");
}); */
// step 2
/* $(".sub").css("display", "none");
$(".title").click(function () {
if ($(this).next().css("display") == "none") {
$(".sub").slideUp(1000);
}
$(this).next().slideToggle(1000);
$(".title").removeClass("on");
$(this).addClass("on");
}); */
// step 3
/* $(".sub").hide();
$(".title").click(function () {
$(".sub").each(function () {
if ($(this).css("display") == "block") {
// 여기서 this는 해당되는 .sub
$(this).slideUp(1000); // 여기서도 this는 해당되는 .sub
}
});
$(this).next().slideDown(); // 여기서 this는 클릭한 title
$(".title").removeClass("on"); // 클래스를 추가할 때는 꼭 지워주고 나서 추가해야함
$(this).addClass("on");
}); */
// step 4
/* $(".sub").hide();
$(".title").click(function () {
if ($(this).hasClass("on") == false) {
// 여기서 this는 클릭한 title / on class가 있으면 true, 없으면 false
$(".title").removeClass("on");
$(this).addClass("on");
$(".sub").slideUp(1000);
$(this).next().slideDown(1000);
} else {
$(this).removeClass("on");
$(this).next().slideUp(1000);
}
}); */
// step 5
/* // 초기 값
$(".sub").hide();
let current;
let num;
function firstmenu() {
$("#navi > li").eq(current).find("ul").slideDown();
}
function init(n) {
current = n;
num = n;
setTimeout(firstmenu, 1000);
}
init(0);
// 클릭 후
$(".title").click(function () {
if ($(this).parent("li").index() != num) {
num = $(this).parent("li").index();
$(".sub").slideUp();
$(this).next().slideDown();
} else {
$(".sub").slideUp();
}
}); */
// step 6
$(".sub").hide();
let current;
function init(n) {
current = n;
setTimeout(firstmenu, 1000);
// setTimeout(만든 함수, 초 ms) - 몇 초가 지나면 저 함수를 실행시켜라~
// setTimeout 함수는 일정시간을 지정해주면 한번만 동작하게 되는데, setInterval 함수에 비해 제한적인 기능을 제공함
}
function firstmenu() {
$("#navi > li").eq(current).find("ul").slideDown(1000);
$(".title").eq(current).addClass("on");
}
$(".title").click(function () {
num = $(this).parent("li").index();
console.log(num);
if ($(this).hasClass("on") == false) {
$(".title").removeClass("on");
$(this).addClass("on");
$(".sub").slideUp(1000);
$(this).next().slideDown(1000);
} else {
$(this).removeClass("on");
$(this).next().slideUp(1000);
}
});
});
<slide animation 예제>
- HTML
<div id="wrap">
<div id="visual">
<ul>
<li class="visual0"><p>배너 이미지1</p></li>
<li class="visual1"><p>배너 이미지2</p></li>
<li class="visual2"><p>배너 이미지3</p></li>
<li class="visual3"><p>배너 이미지4</p></li>
</ul>
</div>
<ul id="page">
<li class="on"><a href="#">배너1</a></li>
<li><a href="#">배너2</a></li>
<li><a href="#">배너3</a></li>
<li><a href="#">배너4</a></li>
</ul>
<ul id="btn">
<li class="prev">이전</li>
<li class="next">다음</li>
</ul>
</div>
- CSS
@font-face {
font-family: pretendard;
src: url(../fontawesome-free-6.2.0-web/webfonts/Pretendard-Regular.woff)
format("woff");
}
* {
padding: 0;
margin: 0;
font: 1em pretendard, Arial, 돋움, Doctum, sans-serif;
}
ul,
li {
list-style: none;
}
a {
text-decoration: none;
color: #333;
}
body {
color: #333;
}
#wrap {
width: 500px;
margin: 0 auto;
}
#visual {
position: relative;
width: 100%;
height: 500px;
overflow: hidden;
}
#visual ul {
position: relative;
width: 100%;
height: 100%;
}
#visual ul li {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
}
#visual ul li p {
font-size: 35px;
line-height: 500px;
}
#visual .visual0 {
left: 0;
background: pink;
}
#visual .visual1 {
left: 100%;
background: rgb(243, 243, 157);
}
#visual .visual2 {
left: 200%;
background: skyblue;
}
#visual .visual3 {
left: 300%;
background: rgb(164, 199, 112);
}
#page {
position: relative;
left: 50%;
transform: translateX(-50%);
}
#page li {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
position: relative;
left: 0;
bottom: 30px;
margin: 0 5px;
cursor: pointer;
background: #000;
}
#page li a {
display: block;
text-indent: -9999px;
}
#page li.on {
background: #fff;
}
#btn {
text-align: center;
}
#btn li {
cursor: pointer;
display: inline-block;
width: 80px;
border: 1px solid #000;
text-align: center;
margin: 10px;
padding: 5px;
}
-jQuery
$(function () {
// 초기 값
let current = 0;
function move(i) {
if (current == i) return;
// current와 i 값이 같으면 다음 구문을 실행하지 말고 빠져나가라는 뜻
$("#visual > ul > li")
.eq(current)
.css({ left: "0" })
.animate({ left: "-100%" });
// 선택한 현재 것만 0이고, 나머지는 다 -100%
$("#visual > ul > li")
.eq(i)
.css({ left: "100%" })
.animate({ left: "0" });
// 클릭을 했을 때도 계속 실행되도록 하는 작업
current = i;
}
$("#page > li").click(function (e) {
e.preventDefault();
var i = $(this).index();
$("#page > li").removeClass("on");
$(this).addClass("on");
move(i);
});
let interval = setInterval(timer, 1800);
function timer() {
var n = current + 1;
if (n == $("#visual > ul > li").length) {
n = 0;
}
$("#page > li").eq(n).trigger("click");
}
function timer_prev() {
var n = current - 1;
if (n == $("visual > ul > li").length) {
n = 0;
}
console.log("n : " + n);
$("#page > li").eq(n).trigger("click");
}
$(".next").click(function () {
timer();
});
$(".prev").click(function () {
timer_prev();
});
$("#page, #btn").hover(
function () {
clearInterval(interval);
},
function () {
// 마우스를 떼면
interval = setInterval(timer, 1000);
}
);
});
점 버튼과 이전/다음 버튼 위에 마우스를 갖다대면 interval이 멈추게 된다.
마우스를 떼면 다시 interval이 시작된다.
이번 예제는 정말 어려웠는데, 몇 번을 보고 또 보니까 조금 이해가 됐다.
사실 아직 혼자서 코드를 막 작성할 자신은 없지만 그래도 조금씩 이해하고 있다 !
처음에 slide animation 했을 때는 정말 너무 어려워서 좌절감에 빠졌는데,,
반복 연습만이 살 길이다...
<owlcarousel2 plugin 사용해보기>
Basic Demo | Owl Carousel | 2.3.4 (owlcarousel2.github.io)
Basic Demo | Owl Carousel | 2.3.4
1 2 3 4 5 6 7 8 9 10 11 12 Basic usage of Owl Carousel. I used loop:true and margin:10. The structure works with any kind of DOM element. In all of my examples i used ... but you could put any other element div/span/a/img...
owlcarousel2.github.io
위의 사이트로 접속하면 반응형 플러그인을 쉽게 이용할 수 있도록 안내되어 있다.
Demo 카테고리에 여러 항목들이 있으니 관심 있는 분은 하나하나 눌러보고 직접 이용해보면 좋을 것 같다.
해당 코드가 공개되어 있고 사이트 상단에 Download를 클릭해 다운 받아서 직접 사용해볼 수 있다.
압축을 풀어 폴더 열어 'owl.carousel.css', 'owl.theme.default.min.css', 'owl.carousel.js'
이 3가지 파일을 찾아 VSCode에서 연결해주면 된다.
- HTML
<div class="owl-carousel owl-theme">
<div class="item"><h4>1</h4></div>
<div class="item"><h4>2</h4></div>
<div class="item"><h4>3</h4></div>
<div class="item"><h4>4</h4></div>
<div class="item"><h4>5</h4></div>
<div class="item"><h4>6</h4></div>
<div class="item"><h4>7</h4></div>
<div class="item"><h4>8</h4></div>
<div class="item"><h4>9</h4></div>
<div class="item"><h4>10</h4></div>
<div class="item"><h4>11</h4></div>
<div class="item"><h4>12</h4></div>
</div>
- CSS
.item {
width: 100%;
height: 300px;
background: #4dc7a0;
}
- jQuery
$(function () {
$(".owl-carousel").owlCarousel({
loop: true,
margin: 0,
nav: true,
items: 1, // item이 한 개만 나오도록 하는 것
autoplay: true, // 가만히 있어도 실행되도록 함
autoplayTimeout: 1500, // 시간은 1.5초 간격으로
autoplayHoverPause: true, // 마우스 hover 했을 때 멈추게 하는 기능
});
});
CSS와 jQuery는 이전에 위의 3가지 파일을 연결해주었기 때문에 내용이 간단하다.
items는 1로 해서 한 페이지에 1개의 item만 나오도록 변경하고, autoplay 속성도 변경해주었다.
<owlcarousel2 plugin 응용>
- HTML
<div class="slide">
<div class="owl-carousel owl-theme">
<div class="item"><img src="img/photo1.jpg" alt="" /></div>
<div class="item"><img src="img/photo2.jpg" alt="" /></div>
<div class="item"><img src="img/photo3.jpg" alt="" /></div>
<div class="item"><img src="img/photo4.jpg" alt="" /></div>
<div class="item"><img src="img/photo5.jpg" alt="" /></div>
<div class="item"><img src="img/photo6.jpg" alt="" /></div>
</div>
</div>
- CSS
@font-face {
font-family: pretendard;
src: url(../fontawesome-free-6.2.0-web/webfonts/Pretendard-Regular.woff)
format("woff");
}
* {
font: 1em pretendard, Arial, 돋움, Doctum, sans-serif;
}
.slide {
max-width: 800px;
margin: 0 auto;
}
.item {
width: 100%;
height: 500px;
margin: 0 auto;
}
.item img {
object-fit: contain;
}
.owl-carousel .owl-nav button.owl-prev,
.owl-carousel .owl-nav button.owl-next {
position: absolute;
top: 40%;
width: 30px;
height: 45px;
background: url(../images/btns.png);
text-indent: -9999px;
}
.owl-carousel .owl-nav button.owl-prev {
left: 50px;
}
.owl-carousel .owl-nav button.owl-next {
right: 50px;
background-position: -30px 0;
}
.owl-theme .owl-nav [class*="owl-"]:hover {
background: rgba(118, 118, 118, 0.5) !important;
color: #fff;
text-decoration: none;
}
.owl-theme .owl-dots .owl-dot span {
background: skyblue !important;
}
.owl-theme .owl-dots .owl-dot.active span,
.owl-theme .owl-dots .owl-dot:hover span {
background: #e1e1e1 !important;
}
CSS는 내가 연결한 css 파일에서 변경해줄 항목들만 긁어와서 !important;를 이용해 속성을
적용했다. 실무에서 플러그인을 사용할 수도 있기 때문에 수정할 줄도 알아야 한다.
- jQuery
$(function () {
$(".owl-carousel").owlCarousel({
loop: true,
margin: 0,
nav: true,
items: 1, // item이 한 개만 나오도록 하는 것
autoplay: true, // 가만히 있어도 실행되도록 함
autoplayTimeout: 1500, // 시간은 1.5초 간격으로
autoplayHoverPause: true, // 마우스 hover 했을 때 멈추게 하는 기능
});
});
<bxslider plugin 사용해보기>
jQuery Content Slider | Responsive jQuery Slider | bxSlider
jQuery Content Slider | Responsive jQuery Slider | bxSlider
Coded with ♥ by
bxslider.com
GitHub - stevenwanderski/bxslider-4: Responsive jQuery content slider
GitHub - stevenwanderski/bxslider-4: Responsive jQuery content slider
Responsive jQuery content slider. Contribute to stevenwanderski/bxslider-4 development by creating an account on GitHub.
github.com
위의 깃허브에서 Download zip을 눌러 압축파일을 다운 받으면 된다.
여기서 필요한 파일은 'jquery.bxslider.min.css', 'jquery.bxslider.js' 2가지이다.
VSCode에서 연결해주자 !
jQuery Content Slider | Responsive jQuery Slider | bxSlider
easing if using CSS: 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'cubic-bezier(n,n,n,n)'. If not using CSS: 'swing', 'linear' (see the above file for more options)
bxslider.com
위의 페이지에서 변경하여 사용할 수 있는 옵션들을 확인할 수 있다.
- HTML
<ul class="bxslider">
<li><img src="images/pic1.jpg" /></li>
<li><img src="images/pic2.jpg" /></li>
<li><img src="images/pic3.jpg" /></li>
<li><img src="images/pic1.jpg" /></li>
<li><img src="images/pic2.jpg" /></li>
</ul>
- CSS
<link href="jquery.bxslider.min.css" rel="stylesheet" />
CSS는 bxslider에서 제공하는 css 파일만 연결해주었다.
- jQuery
$(document).ready(function () {
$(".bxslider").bxSlider({
mode: "fade", // 'horizontal(수평)', 'vertical(수직)', 'fade'
moveSlides: 1, // 한 페이지 안에 나오는 슬라이드 개수
slideMargin: 0, // 슬라이드 사이 간격. 한 개만 나오도록 했기 때문에 0으로 변경함
infiniteLoop: true,
slideWidth: 660,
minSlides: 1,
maxSlides: 1,
speed: 800,
auto: true,
autoHover: true,
});
});
<bxslider 응용해보기>
- HTML
<div class="slider">
<div class="bxslider">
<div class="item"><img src="img/photo1.jpg" /></div>
<div class="item"><img src="img/photo2.jpg" /></div>
<div class="item"><img src="img/photo3.jpg" /></div>
<div class="item"><img src="img/photo4.jpg" /></div>
<div class="item"><img src="img/photo5.jpg" /></div>
<div class="item"><img src="img/photo6.jpg" /></div>
</div>
</div>
- CSS
.slide {
position: relative;
width: 1200px;
margin: 0 auto;
}
.bxslider {
width: 100%;
}
.item {
width: 100%;
}
.item img {
width: 100%;
height: 400px;
object-fit: cover;
}
아까 연결했던 bxslider에서 제공하는 css 파일도 연결해주었다.
- jQuery
$(document).ready(function () {
$(".bxslider").bxSlider({
mode: "horizontal", // 'horizontal(수평)', 'vertical(수직)', 'fade'
moveSlides: 1, // 한 페이지 안에 나오는 슬라이드 개수
slideMargin: 0, // 슬라이드 사이 간격. 한 개만 나오도록 했기 때문에 0으로 변경함
infiniteLoop: true,
slideWidth: 1200,
minSlides: 1,
maxSlides: 1,
speed: 800,
auto: true, // 자동으로 슬라이드 넘어가도록 함
autoHover: true, // hover 하면 슬라이드 멈춤, 마우스 떼면 다시 넘어감
pause: 1200, // auto transition 각각에 시간 간격
});
});
<mousewheel event 알아보기>
- HTML
<ul id="menu">
<li class="on"><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
</ul>
<div id="wrap">
<section>
<article></article>
</section>
<section>
<article></article>
</section>
<section>
<article></article>
</section>
<section>
<article></article>
</section>
</div>
- CSS
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
html,
body {
width: 100%;
height: 100%;
}
#menu {
position: fixed;
top: 50%;
left: 0;
margin-top: -100px;
z-index: 15;
}
#menu li a {
display: block;
width: 10px;
height: 10px;
background: #000;
opacity: 0.8;
transition: all 0.5s;
}
#menu li:hover a {
font-size: 24px;
opacity: 1;
color: #fff;
border-color: #fff;
}
#menu li.on a {
border-color: #d4164c;
background: #fff;
font-size: 24px;
opacity: 1;
}
section {
position: relative;
width: 100%;
/* height: 100%; */
}
section:nth-child(1) {
background: red;
}
section:nth-child(2) {
background: yellow;
}
section:nth-child(3) {
background: blue;
}
section:nth-child(4) {
background: green;
}
- jQuery
여기서는 이 파일을 다운 받아 연결해주어야 한다.
$(function () {
let ht = $(window).height();
$("section").height(ht);
$(window).resize(function () {
let ht = $(window).height();
$("section").height(ht);
});
$(window).scroll(function () {});
$("section").on("mousewheel", function (event, delta) {
console.log(delta);
if (delta > 0) {
if ($(this).next() != undefined) {
try {
let prev = $(this).prev().offset().top;
console.log("prev :" + prev);
// 문서 전체를 prev에 저장된 위치로 이동
$("html,body")
.stop()
.animate({ scrollTop: prev }, 1400, "easeOutBounce");
} catch (e) {}
}
// 변수 prev에 현재 휠을 움직인 section에서 이전 section의 offset().top위치 저장
// 마우스 휠을 내렸을때
} else if (delta < 0) {
if ($(this).next() != undefined) {
try {
// 변수 next에 현재 휠을 움직인 section에서 다음 section의 offset().top위치 저장
let next = $(this).next().offset().top;
// 문서 전체를 next에 저장된 위치로 이동
$("html,body")
.stop()
.animate({ scrollTop: next }, 1400, "easeOutBounce");
} catch (e) {}
}
}
});
});
delta란 매개변수로 손쉽게 쓸 수 있다.
마우스 휠 이벤트에서 휠을 위로 올리면 console 창에서 확인할 수 있듯이 양수로 나오고,
휠을 아래로 내리면 음수로 나온다.