롤링배너(?) 갤러리 정보
롤링배너(?) 갤러리
본문
https://sir.kr/qa/495896 - 질문이 올라와서 예전에 만들어 두었던 것을 약간 보층해서 코드 공유합니다.
제가 별로 안 쓰는 형태라 개별버튼은 안 만들었습니다.^^
장면전환시 애니메이션 css 를 쓰지 않고 레거시(?)한 방식으로 감속탄성 코드를 자바스크립트에서 만들었습니다.
https://wittazzurri.com/editor/html_editor.php 에서 확인해 보세요.
image_1 부터 image_n 까지 원하는 대로...
<style>
#galleryDiv { position:relative; margin:0 auto; }
#imageDiv { overflow:hidden; }
#imageDiv div { display:flex; width:200%; }
#imageDiv img { display:block; width:50%; }
#buttonDiv { position:absolute; top:0px; width:100%; height:100%; padding:20px; display:flex; justify-content:space-between; align-items:center; box-sizing:border-box; }
#buttonDiv img { display:block; cursor:pointer; width:50px; height:50px; }
</style>
<div id="galleryDiv">
<div id="imageDiv"><div><img><img></div></div>
<div id="buttonDiv"><img><img></div>
</div>
<script>
autoSec = 5; // 자동넘기기 - 초단위
targetSpeed = 10; // 장면전환 속도 - 숫자가 커질수록 느려짐
leftButton = "https://blog.kakaocdn.net/dn/I1GYB/btq8bL8uxVv/guiZYpTMedre9zj97Y1jk0/img.png"; // 좌버튼 이미지
rightButton = "https://blog.kakaocdn.net/dn/bniCh0/btq8bsg19MB/PJUsaJdJkpJdbkHcWUC9wk/img.png"; // 우버튼 이미지
image_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";
image_2 = "https://blog.kakaocdn.net/dn/zYSgG/btr8P0DskTO/i6JzVmVy3gsM5by353o3E0/img.jpg";
image_3 = "https://blog.kakaocdn.net/dn/bD8PyW/btr8LgN5SsY/AvjSnqZ0xgsM3FvpHsaDh1/img.jpg";
image_4 = "https://blog.kakaocdn.net/dn/dSddpv/btr8Mn64wqT/b5P6xKyDYfVXuDOeEtcKtK/img.jpg";
image_5 = "https://blog.kakaocdn.net/dn/cBCuTv/btr8J48xbjE/e5z35o9vMjSJeYJA8auRJ1/img.jpg";
buttonDiv.querySelectorAll("img")[0].src = leftButton;
buttonDiv.querySelectorAll("img")[1].src = rightButton;
for (imgTotal = 0; this["image_" + (imgTotal + 1)]; imgTotal++);
function imageMode() {
imageDiv.querySelectorAll("img")[0].src = this["image_" + arguments[0]];
imageDiv.querySelectorAll("img")[1].src = this["image_" + (arguments[0] === imgTotal ? 1 : ++arguments[0])];
targetCount = 0;
}
addEventListener("resize", galleryMode = () => {
galleryDiv.style.width = "100%";
galleryWidth = Math.floor(galleryDiv.offsetWidth);
galleryDiv.style.width = galleryWidth + "px";
galleryPoint = -galleryWidth;
imageDiv.querySelector("div").style.marginLeft = "0px";
} );
galleryMode();
imageMode(img = 1);
buttonDiv.querySelectorAll("img")[0].onclick = () => {
targetCount = autoSec * 100;
for (ic of document.querySelectorAll("#imageDiv, #imageDiv img")) ic.style.transform = "rotateY(180deg)";
}
buttonDiv.querySelectorAll("img")[1].onclick = () => {
targetCount = autoSec * 100;
for (ic of document.querySelectorAll("#imageDiv, #imageDiv img")) ic.style.transform = "rotateY(0deg)";
}
setInterval(() => {
++targetCount;
changePoint = Number(imageDiv.querySelector("div").style.marginLeft.slice(0, -2));
if (Math.abs(changePoint - galleryPoint) <= 0.5) {
imageDiv.querySelector("div").style.marginLeft = "0px";
imageMode(img = img === imgTotal ? 1 : ++img);
}
else {
if (targetCount >= 0 && targetCount < autoSec * 100) changePoint = 0;
else changePoint += (galleryPoint - changePoint) / targetSpeed;
imageDiv.querySelector("div").style.marginLeft = changePoint + "px";
}
}, 10);
</script>
추천
6
6
댓글 20개

좋아요, 감사 합니다.

@들레아빠 감사합니다. 참고로
image_1 에서 image_n 까지 최종숫자 n 을 추출하는 코드는 아래처럼 imgTotal 을 추출하는 것이 좋습니다. 최종숫자를 입력할 필요가 없거든요.
for (imgTotal = 0; this["image_" + (imgTotal + 1)]; imgTotal++);
https://sir.kr/g5_tip/16115
image_1 에서 image_n 까지 최종숫자 n 을 추출하는 코드는 아래처럼 imgTotal 을 추출하는 것이 좋습니다. 최종숫자를 입력할 필요가 없거든요.
for (imgTotal = 0; this["image_" + (imgTotal + 1)]; imgTotal++);
https://sir.kr/g5_tip/16115

@비타주리 네, 감사 합니다.
for (var i = 1; i <= 5; i++){
this['image_' + i] = ["/img/banner/"+i+".jpg"];
}

@들레아빠
<script>
image_1 = ["1.jpg"];
document.write(typeof image_1);
</script>
<br>
<script>
image_1 = "1.jpg";
document.write(typeof image_1);
</script>
이리하면 변수의 타입이 처음은 오브젝트(배열등) 다음은 스트링(문자열)으로 나타납니다.
단순 문자열을 굳이 배열에 담아 리소스를 키울 필요가 없거든요.
아래처럼 바꾸세요.
this['image_' + i] = "/img/banner/"+i+".jpg";
<script>
image_1 = ["1.jpg"];
document.write(typeof image_1);
</script>
<br>
<script>
image_1 = "1.jpg";
document.write(typeof image_1);
</script>
이리하면 변수의 타입이 처음은 오브젝트(배열등) 다음은 스트링(문자열)으로 나타납니다.
단순 문자열을 굳이 배열에 담아 리소스를 키울 필요가 없거든요.
아래처럼 바꾸세요.
this['image_' + i] = "/img/banner/"+i+".jpg";

@비타주리 역시 !! 대단히 감사 합니다.
좋습니다^^
자바스크립트로 만든 갤러리가 오류도 안나고 그누보드 버전에 관계없이 사용할 수있어서 좋은것 같습니다
이미지에 링크를 주려면 이미지 앞에 a 태그를 사용해서 하는데요.
<a href="https://sir.kr">image_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";</a>
이렇게 하면 될것 같은데, 적용해 보니 잘 안되는데요.
링크에도 for 문을 사용해야 되는지요.
감사합니다.
자바스크립트로 만든 갤러리가 오류도 안나고 그누보드 버전에 관계없이 사용할 수있어서 좋은것 같습니다
이미지에 링크를 주려면 이미지 앞에 a 태그를 사용해서 하는데요.
<a href="https://sir.kr">image_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";</a>
이렇게 하면 될것 같은데, 적용해 보니 잘 안되는데요.
링크에도 for 문을 사용해야 되는지요.
감사합니다.

@김철용
1. 링크영역의 최대확보를 위해 #buttonDiv 의 padding 을
padding:20px; 에서 padding:0px 20px; 으로 바꿉니다.
2. css 에서 a 를 정의해 주구요. 시각화를 위해 배경색을 red 로 깔아줍니다.
#buttonDiv a { width:100%; height:100%; background-color:red; }
3. <div id="buttonDiv"><img><img></div> 를 아래처럼 고치고요.
<div id="buttonDiv"><img><a target="_blank"></a><img></div>
4. image_1 부터 image_5 아래에 같은 숫자의 링크 변수를 만들어 줍니다.
link_1 = "1번링크주소";
link_2 = "2번링크주소";
link_3 = "3번링크주소";
link_4 = "4번링크주소";
link_5 = "5번링크주소";
5. function imageMode() 의 가장 상단에 링크코드를 한줄만 더 첨가합니다.
6. 확인이 끝났으면 2번에서 배경 빨간색을 삭제합니다.
#buttonDiv a { width:100%; height:100%; }
그래서 최종으로...
1. 링크영역의 최대확보를 위해 #buttonDiv 의 padding 을
padding:20px; 에서 padding:0px 20px; 으로 바꿉니다.
2. css 에서 a 를 정의해 주구요. 시각화를 위해 배경색을 red 로 깔아줍니다.
#buttonDiv a { width:100%; height:100%; background-color:red; }
3. <div id="buttonDiv"><img><img></div> 를 아래처럼 고치고요.
<div id="buttonDiv"><img><a target="_blank"></a><img></div>
4. image_1 부터 image_5 아래에 같은 숫자의 링크 변수를 만들어 줍니다.
link_1 = "1번링크주소";
link_2 = "2번링크주소";
link_3 = "3번링크주소";
link_4 = "4번링크주소";
link_5 = "5번링크주소";
5. function imageMode() 의 가장 상단에 링크코드를 한줄만 더 첨가합니다.
function imageMode() {
buttonDiv.querySelector("a").href = this["link_" + arguments[0]];
imageDiv.querySelectorAll("img")[0].src = this["image_" + arguments[0]];
imageDiv.querySelectorAll("img")[1].src = this["image_" + (arguments[0] === imgTotal ? 1 : ++arguments[0])];
targetCount = 0;
}
6. 확인이 끝났으면 2번에서 배경 빨간색을 삭제합니다.
#buttonDiv a { width:100%; height:100%; }
그래서 최종으로...
<style>
#galleryDiv { position:relative; margin:0 auto; }
#imageDiv { overflow:hidden; }
#imageDiv div { display:flex; width:200%; }
#imageDiv img { display:block; width:50%; }
#buttonDiv { position:absolute; top:0px; width:100%; height:100%; padding:0px 20px; display:flex; justify-content:space-between; align-items:center; box-sizing:border-box; }
#buttonDiv img { display:block; cursor:pointer; width:50px; height:50px; }
#buttonDiv a { width:100%; height:100%; }
</style>
<div id="galleryDiv">
<div id="imageDiv"><div><img><img></div></div>
<div id="buttonDiv"><img><a target="_blank"></a><img></div>
</div>
<script>
autoSec = 5; // 자동넘기기 - 초단위
targetSpeed = 10; // 슬라이드 속도 - 숫자가 커질수록 느려짐
leftButton = "https://blog.kakaocdn.net/dn/I1GYB/btq8bL8uxVv/guiZYpTMedre9zj97Y1jk0/img.png"; // 좌버튼 이미지
rightButton = "https://blog.kakaocdn.net/dn/bniCh0/btq8bsg19MB/PJUsaJdJkpJdbkHcWUC9wk/img.png"; // 우버튼 이미지
image_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";
image_2 = "https://blog.kakaocdn.net/dn/zYSgG/btr8P0DskTO/i6JzVmVy3gsM5by353o3E0/img.jpg";
image_3 = "https://blog.kakaocdn.net/dn/bD8PyW/btr8LgN5SsY/AvjSnqZ0xgsM3FvpHsaDh1/img.jpg";
image_4 = "https://blog.kakaocdn.net/dn/dSddpv/btr8Mn64wqT/b5P6xKyDYfVXuDOeEtcKtK/img.jpg";
image_5 = "https://blog.kakaocdn.net/dn/cBCuTv/btr8J48xbjE/e5z35o9vMjSJeYJA8auRJ1/img.jpg";
link_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";
link_2 = "https://blog.kakaocdn.net/dn/zYSgG/btr8P0DskTO/i6JzVmVy3gsM5by353o3E0/img.jpg";
link_3 = "https://blog.kakaocdn.net/dn/bD8PyW/btr8LgN5SsY/AvjSnqZ0xgsM3FvpHsaDh1/img.jpg";
link_4 = "https://blog.kakaocdn.net/dn/dSddpv/btr8Mn64wqT/b5P6xKyDYfVXuDOeEtcKtK/img.jpg";
link_5 = "https://blog.kakaocdn.net/dn/cBCuTv/btr8J48xbjE/e5z35o9vMjSJeYJA8auRJ1/img.jpg";
buttonDiv.querySelectorAll("img")[0].src = leftButton;
buttonDiv.querySelectorAll("img")[1].src = rightButton;
for (imgTotal = 0; this["image_" + (imgTotal + 1)]; imgTotal++);
function imageMode() {
buttonDiv.querySelector("a").href = this["link_" + arguments[0]];
imageDiv.querySelectorAll("img")[0].src = this["image_" + arguments[0]];
imageDiv.querySelectorAll("img")[1].src = this["image_" + (arguments[0] === imgTotal ? 1 : ++arguments[0])];
targetCount = 0;
}
addEventListener("resize", galleryMode = () => {
galleryDiv.style.width = "100%";
galleryWidth = Math.floor(galleryDiv.offsetWidth);
galleryDiv.style.width = galleryWidth + "px";
galleryPoint = -galleryWidth;
imageDiv.querySelector("div").style.marginLeft = "0px";
} );
galleryMode();
imageMode(img = 1);
buttonDiv.querySelectorAll("img")[0].onclick = () => {
targetCount = autoSec * 100;
for (ic of document.querySelectorAll("#imageDiv, #imageDiv img")) ic.style.transform = "rotateY(180deg)";
}
buttonDiv.querySelectorAll("img")[1].onclick = () => {
targetCount = autoSec * 100;
for (ic of document.querySelectorAll("#imageDiv, #imageDiv img")) ic.style.transform = "rotateY(0deg)";
}
setInterval(() => {
++targetCount;
changePoint = Number(imageDiv.querySelector("div").style.marginLeft.slice(0, -2));
if (Math.abs(changePoint - galleryPoint) <= 0.5) {
imageDiv.querySelector("div").style.marginLeft = "0px";
imageMode(img = img === imgTotal ? 1 : ++img);
}
else {
if (targetCount >= 0 && targetCount < autoSec * 100) changePoint = 0;
else changePoint += (galleryPoint - changePoint) / targetSpeed;
imageDiv.querySelector("div").style.marginLeft = changePoint + "px";
}
}, 10);
</script>

감사합니다.
배울게 산더미 같군요..ㅎ
배너 공부하는데 엄청 도움이 될 것 같습니다.
그런데 브라우저 리사이즈할 때 그림이 자동 확대,축소가 되지 않아
galleryWidth = Math.floor(galleryDiv.offsetWidth);
이 라인을
galleryWidth = window.innerWidth;
이렇게 바꿨더니 제대로 되는것 같습니다.
바꿔도 별 문제 없겠지요??
배울게 산더미 같군요..ㅎ
배너 공부하는데 엄청 도움이 될 것 같습니다.
그런데 브라우저 리사이즈할 때 그림이 자동 확대,축소가 되지 않아
galleryWidth = Math.floor(galleryDiv.offsetWidth);
이 라인을
galleryWidth = window.innerWidth;
이렇게 바꿨더니 제대로 되는것 같습니다.
바꿔도 별 문제 없겠지요??

@도레미 리사이즈 이벤트의 경우 저는 모바일에서 가로 세로 전환 또는 그 역전환만 신경씁니다.
pc는 신경도 안 쓰거든요.ㅋ
그런데 도레미님처럼 하면 가령 갤러리 가로를 pc에서는 900픽셀 모바일에서는 100퍼센트로 주는 식은 힘들고 오직 가로 이빠이 이벤트만 될 터이라...
본인이 편한 방식대로 쓰면 되죠.
제가 Math.floor 을 준 이유는 예를 들어 상위 엘레먼트가 1001픽셀이고 여기에 90퍼센트로 크기를 주면 픽셀값이 소숫점으로 나와요.
그럼 셋인터벌을 오래 놔두면 사이즈 삑사리가 나서 보기가 싫어집니다.
그래서 버림값 자연수를 취해서 딱 떨어지게 맞추어야 장기간 셋인터벌에서도 소숫점 삑사리가 나지 않습니다.
pc는 신경도 안 쓰거든요.ㅋ
그런데 도레미님처럼 하면 가령 갤러리 가로를 pc에서는 900픽셀 모바일에서는 100퍼센트로 주는 식은 힘들고 오직 가로 이빠이 이벤트만 될 터이라...
본인이 편한 방식대로 쓰면 되죠.
제가 Math.floor 을 준 이유는 예를 들어 상위 엘레먼트가 1001픽셀이고 여기에 90퍼센트로 크기를 주면 픽셀값이 소숫점으로 나와요.
그럼 셋인터벌을 오래 놔두면 사이즈 삑사리가 나서 보기가 싫어집니다.
그래서 버림값 자연수를 취해서 딱 떨어지게 맞추어야 장기간 셋인터벌에서도 소숫점 삑사리가 나지 않습니다.

@도레미
테이블 css 에 table-layout:fixed 를 주면 소숫점 삑사리가 나지 않습니다.
그외 다른 엘레먼트로 flex 또는 grid 로 만들면 테이블처럼 정확하지 않고 문제가 발생해서...
그렇게 테이블로 코드를 짜면 웹표준이네 뭐네 하는 소리 듣기 싫어서 첨부터 버림값 자연수를 취해 마진제로오토로 중앙정렬시켜서 코드를 짜게 되더라구요.ㅋ
테이블 css 에 table-layout:fixed 를 주면 소숫점 삑사리가 나지 않습니다.
그외 다른 엘레먼트로 flex 또는 grid 로 만들면 테이블처럼 정확하지 않고 문제가 발생해서...
그렇게 테이블로 코드를 짜면 웹표준이네 뭐네 하는 소리 듣기 싫어서 첨부터 버림값 자연수를 취해 마진제로오토로 중앙정렬시켜서 코드를 짜게 되더라구요.ㅋ

@도레미
아 제일 중요한 걸 빼먹었네요. pc 에서도 리사이징을 원하시면...
galleryWidth = Math.floor(galleryDiv.offsetWidth);
이 코드 위에 한줄만 더 보태주면 됩니다. 아래처럼요.
galleryDiv.style.width = "100%";
galleryWidth = Math.floor(galleryDiv.offsetWidth);
본문코드도 고쳤어요
아 제일 중요한 걸 빼먹었네요. pc 에서도 리사이징을 원하시면...
galleryWidth = Math.floor(galleryDiv.offsetWidth);
이 코드 위에 한줄만 더 보태주면 됩니다. 아래처럼요.
galleryDiv.style.width = "100%";
galleryWidth = Math.floor(galleryDiv.offsetWidth);
본문코드도 고쳤어요

왜 굳이 Math.floor 를 썼을까 궁금했었습니다.
오~ 알수록 오묘합니다....ㅎ
오~ 알수록 오묘합니다....ㅎ

@도레미 감사합니다

감사합니다.

@써맨 감사합니다

활용하기 완전 좋네요.
추천 합니다.
추천 합니다.

@푸른산타
감사합니다. 지금보니 손 볼것이 또 있네요.ㅜㅠ
감사합니다. 지금보니 손 볼것이 또 있네요.ㅜㅠ
멋집니다. 그리고 대단하세요~ 추천!

@브러운아이 감사합니다

감사합니다.