# 12.슬라이드

In 

# 목차

  • 1. 기본 슬라이드
    • 1.1. fadeInOut
      • 1.1.1. 메서드 활용
      • 1.1.2. 클래스 활용
    • 1.2. 이동
  • 2. 인디케이터가 있는 슬라이드

# 1. 기본 슬라이드

# 1.1. fadeInOut

# 1.1.1. 메서드 활용

미리보기
https://qwerewqwerew.github.io/source/jq/12/12b-jq.html

리소스 이미지

http://qwerew.cafe24.com/images/1.jpg
http://qwerew.cafe24.com/images/2.jpg
http://qwerew.cafe24.com/images/3.jpg
http://qwerew.cafe24.com/images/4.jpg
http://qwerew.cafe24.com/images/5.jpg
http://qwerew.cafe24.com/images/6.jpg
http://qwerew.cafe24.com/images/7.jpg
http://qwerew.cafe24.com/images/8.jpg
http://qwerew.cafe24.com/images/9.jpg
http://qwerew.cafe24.com/images/10.jpg
html
<body>
	<div id="content">
		<h3>Simple Crossfade Waterfalls Slideshow</h3>
		<ul id="crossfade">
			<li>
				<a href="#"><img src="http://qwerew.cafe24.com/images/1.jpg" alt="" /></a>
				<p>1번</p>
			</li>
			<li>
				<a href="#"><img src="http://qwerew.cafe24.com/images/2.jpg" alt="" /></a>
				<p>2번</p>
			</li>
			<li>
				<a href="#"><img src="http://qwerew.cafe24.com/images/3.jpg" alt="" /></a>
				<p>3번</p>
			</li>
		</ul>
	</div>
</body>
css
#crossfade {
	position: relative;
	margin: auto;
	padding: 0;
	list-style-type: none;
	width: 600px;
	height: 400px;
	overflow: hidden;
}

#crossfade li {
	position: absolute;
	width: 600px;
	height: 400px;
}

#crossfade p {
	position: absolute;
	bottom: 0;
	padding: 20px;
	color: #fff;
	background: #000;
	background-color: rgba(0, 0, 0, 0.6);
	margin: 0;
	left: 0;
	right: 0;
}

방법1

JQ
$(() => {
	$('#crossfade li').hide().filter(':first').show();
	setInterval(slideshow, 3000);
	function slideshow() {
		$('#crossfade li:first').fadeOut('slow').next().fadeIn('slow').end().appendTo('#crossfade');
	}
});

방법2

JQ
$(() => {
	let idx = 0;
	$('#crossfade li').hide();
	$('#crossfade li').eq(0).show();
	setInterval(slideshow, 3000);
	function slideshow() {
		$('#crossfade li').eq(idx).fadeOut('slow');
		idx++;
		if (idx > $('#crossfade li').length - 1) {
			idx = 0;
		}
		$('#crossfade li').eq(idx).fadeIn('slow');
	}
});

# 1.1.2. 클래스 활용

미리보기
https://qwerewqwerew.github.io/source/jq/12/12c-jq.html

html
<body>
	<div id="content">
		<h3>Simple Crossfade Waterfalls Slideshow</h3>
		<ul id="crossfade">
			<li>
				<a href="#"><img src="http://qwerew.cafe24.com/images/1.jpg" alt="" /></a>
				<p>1번</p>
			</li>
			<li>
				<a href="#"><img src="http://qwerew.cafe24.com/images/2.jpg" alt="" /></a>
				<p>2번</p>
			</li>
			<li>
				<a href="#"><img src="http://qwerew.cafe24.com/images/3.jpg" alt="" /></a>
				<p>3번</p>
			</li>
		</ul>
	</div>
</body>
css
#crossfade {
	position: relative;
	margin: auto;
	padding: 0;
	list-style-type: none;
	width: 600px;
	height: 400px;
	overflow: hidden;
}

#crossfade li {
	position: absolute;
	width: 600px;
	height: 400px;
	opacity: 0;
	transition: opacity 0.5s;
}

#crossfade p {
	position: absolute;
	bottom: 0;
	padding: 20px;
	color: #fff;
	background: #000;
	background-color: rgba(0, 0, 0, 0.6);
	margin: 0;
	left: 0;
	right: 0;
}
JQ
$(() => {
	$('#crossfade li').hide().filter(':first').show();
	setInterval(slideshow, 3000);
	function slideshow() {
		$('#crossfade li:first').fadeOut('slow').next().fadeIn('slow').end().appendTo('#crossfade');
	}
});

# 1.2. 이동

jQuery1 미리보기
https://qwerewqwerew.github.io/source/jq/12/12d-jq.html

jQuery2 미리보기
https://qwerewqwerew.github.io/source/jq/12/12e-jq.html

<div id="content">
	<h3>Slideshow</h3>
	<ul id="crossfade">
		<li>
			<a href="#"><img src="http://qwerew.cafe24.com/images/1.jpg" alt="" /></a>
			<p>1번</p>
		</li>
		<li>
			<a href="#"><img src="http://qwerew.cafe24.com/images/2.jpg" alt="" /></a>
			<p>2번</p>
		</li>
		<li>
			<a href="#"><img src="http://qwerew.cafe24.com/images/3.jpg" alt="" /></a>
			<p>3번</p>
		</li>
	</ul>
</div>
#crossfade {
	position: relative;
	margin: auto;
	padding: 0;
	list-style-type: none;
	width: 600px;
	height: 400px;
	overflow: hidden;
}

#crossfade li {
	position: absolute;
	width: 600px;
	height: 400px;
}

#crossfade p {
	position: absolute;
	bottom: 0;
	padding: 20px;
	color: #fff;
	background: #000;
	background-color: rgba(0, 0, 0, 0.6);
	margin: 0;
	left: 0;
	right: 0;
}
const slide = $('#crossfade li');

// 정렬
slide.each((i, o) => {
	$(o).css('left', i * 100 + '%');
});

let idx = 0;

// 무한루프를 위한 setInterval
setInterval(() => {
	slide
		.eq(idx)
		.stop()
		.animate({ left: -100 + '%' }, 1000, function () {
			$(this).css('left', (slide.length - 1) * 100 + '%');
		});
	idx++;
	if (idx > slide.length - 1) {
		idx = 0;
	}
	slide
		.eq(idx)
		.stop()
		.animate({ left: 0 + '%' }, 1000);
}, 3000); // 3초마다 반복
		const slide = $('#crossfade li');
		let current = 0;
		// 정렬
		slide.each((i, o) => {
			$(o).css('left', i * 100 + '%');
		});

		setInterval(function () {
			var prev = slide.eq(current);
			move(prev, 0, '-100%');
			current++;
			if (current == slide.length) {
				current = 0;
			}
			var next = slide.eq(current);
			move(next, '100%', '0%');
		}, 3000);

		function move(tg, start, end) {
			tg.css('left', start).stop().animate({ left: end }, 1000);
		}

# 2. 인디케이터가 있는 슬라이드

제이쿼리슬라이드 자바스크립트슬라이드

이미지다운로드

index.html
<div class="slide_wrap">
	<div class="brand_visual">
		<ul>
			<li class="visual_0"><a href="#">배너이미지1</a></li>
			<li class="visual_1"><a href="#">배너이미지2</a></li>
			<li class="visual_2"><a href="#">배너이미지3</a></li>
		</ul>
	</div>
	<div class="btns">
		<img src="img/left.png" class="prev" width="30" height="50" alt="" />
		<img src="img/right.png" class="next" width="30" height="50" alt="" />
	</div>
	<ul class="buttons">
		<li class="on"><a href="#">배너1</a></li>
		<li><a href="#">배너2</a></li>
		<li><a href="#">배너3</a></li>
	</ul>
</div>
reset.css
/* common */
html {
	width: 100%;
	height: 100%;
	overflow-y: scroll;
}
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
	margin: 0px;
	padding: 0px;
	font: inherit;
	vertical-align: baseline;
}
body {
	font-size: 12px;
	font-family: Dotum, Arial;
	color: #74767a;
	line-height: 120%;
}
a,
a:link,
a:visited {
	color: #74767a;
	text-decoration: none;
}
ul,
ol {
	list-style: none;
}
table,
fieldset,
th,
td,
img {
	border: none;
}
img,
input,
select {
	vertical-align: middle;
}
style.css
.slide_wrap{position:relative;}
.brand_visual ul {
	overflow: hidden;
	position: relative;
	width: 100%;
	height: clamp(50vh,500px,20vh);
}
.brand_visual ul li {
	position: absolute;
	width: 100%;
	height: 100%;
}
 /* 글씨 제거 */
.brand_visual ul li a {
	display: block;
	text-indent: -9999px;
}

/* visual_0, visual_1, visual_2 위치정렬 */
.brand_visual .visual_0 {
	left: 0;
	background: url(img/0.png) 50% 0 no-repeat;
}
.brand_visual .visual_1 {
	left: 100%;
	background: url(img/1.png) 50% 0 no-repeat;
}
.brand_visual .visual_2 {
	left: 200%;
	background: url(img/2.png) 50% 0 no-repeat;
}

/* 화살표 */
.btns {
	position: relative;
	top: -250px;
	width: 100%;
}
.btns .prev {
	position: absolute;
	left: 100px;
}
.btns .next {
	position: absolute;
	right: 100px;
}

/* 버튼 위치 지정 */
.buttons {
	display: flex;
	position: absolute;
	left: 50%;
	top: -135px;
	gap:10px;
	transform:translateX(-50%);
}
.buttons li {
	background: url(img/btnVisual.png) 0 -16px no-repeat;
	width: 14px;
	height: 15px;
	overflow: hidden;
	cursor: pointer;
}
/* 글씨 제거 */
.buttons li a {
	display: block;
	text-indent: -9999px;
}
/* 활성화된 버튼 */
.buttons li.on {
	background-position: 0 0;
}
$(() => {
	const visual = $('.brand_visual>ul>li');
	const button = $('.buttons>li');
	const leftBtn = $('.btns .prev');
	const rightBtn = $('.btns .next');
	let setIntervalId;
	const counter = $('.counter');

	let current = 0;

	function timer() {
		setIntervalId = setInterval(function () {
			changeSlide((current + 1) % visual.length); // 0%3=0/1%3=1/2%3=2/3%3=0
		}, 3000);
	}

	function move(tg, start, end) {
		tg.css('left', start).stop().animate({ left: end }, { duration: 500, ease: 'easeOutCubic' });
	}

	function cnt(num) {
		counter.html(`${num + 1}`);
	}

	button.on('click', function () {
		const i = $(this).index();
		changeSlide(i);
	});

	function changeSlide(i, direction = 'right') {
		if (current == i) return;
		const currentEl = visual.eq(current);
		const nextEl = visual.eq(i);
		if (direction === 'right') {
			move(currentEl, 0, '-100%');
			move(nextEl, '100%', 0);
		} else {
			move(currentEl, 0, '100%');
			move(nextEl, '-100%', 0);
		}
		button.eq(current).removeClass('on');
		button.eq(i).addClass('on');
		cnt(i);
		current = i;
	}

	$('.slide_wrap').on({
		mouseover: function () {
			clearInterval(setIntervalId);
		},
		mouseout: timer,
	});

	rightBtn.click(function () {
		changeSlide((current + 1) % visual.length);
		return false;
	});

	leftBtn.click(function () {
		changeSlide((current - 1 + visual.length) % visual.length, 'left');
		return false;
	});

	timer(); // timer를 마지막에 호출하여 초기 슬라이드 쇼를 시작
});
const visual = document.querySelectorAll('#brandVisual>ul>li');
const button = document.querySelectorAll('#buttonList>li');
const leftBtn = document.querySelector('.btnImg .prev');
const rightBtn = document.querySelector('.btnImg .next');
let current = 0;
let setIntervalId;
let isMove = false;

// 슬라이드 이동
function moveSlide(prevIndex, nextIndex) {
	if (isMove) return;
	isMove = true;
	move(visual[prevIndex], 0, '-100%');
	button[prevIndex].classList.remove('on');
	move(visual[nextIndex], '100%', 0);
	button[nextIndex].classList.add('on');
	current = nextIndex;
}

// 애니메이션
function move(tg, start, end) {
	let keyframes = [{ left: start }, { left: end }];
	let options = { duration: 1000, fill: 'forwards' };
	let animation = tg.animate(keyframes, options);
	animation.onfinish = () => {
		isMove = false;
	};
}

// 타이머
function timer() {
	setIntervalId = setInterval(() => {
		let nextIndex = (current + 1) % visual.length;
		moveSlide(current, nextIndex);
	}, 3000);
}

setTimeout(timer, 1000);

// 이벤트 리스너들
document.querySelector('#wrap').addEventListener('mouseover', () => clearInterval(setIntervalId));
document.querySelector('#wrap').addEventListener('mouseout', timer);

button.forEach((btn, i) => {
	btn.addEventListener('click', () => moveSlide(current, i));
});

rightBtn.addEventListener('click', (e) => {
	e.preventDefault();
	let nextIndex = (current + 1) % visual.length;
	moveSlide(current, nextIndex);
});

leftBtn.addEventListener('click', (e) => {
	e.preventDefault();
	let nextIndex = (current - 1 + visual.length) % visual.length;
	moveSlide(current, nextIndex);
});