[Javascript] 스크롤에 따른 버튼 처리, 내용이 요소의 크기를 벗어났을 때

yugyeongKim·2022년 10월 2일
0

Javascript

목록 보기
4/7

✅스크롤에 따른 버튼 처리

1. 요소 실제 크기 찾기 : element.scollWidth

  • scrollWidth, scrollHeight: 요소의 숨겨져있는 진짜 크기

  • clientWidth, clientHeight: 현재 보여지는 요소의 크기

총 크기를 구해서 스크롤숫자 num으로 나눈다.
scrollLeft가 num * ((num / 총크기)- 1) 와 같으면 오른쪽 버튼을 없앤다.

버튼을 클릭할 때는 스크롤이 움직이기 전이니 -1을 해주는 것.

왼쪽버튼은 맨처음에 안보이게 하고 scrollLeft가 num보다 작으면 다시 왼쪽버튼을 없애준다.

const cakeListWidth = $cakeList.scrollWidth;
const num = 800;

$rightBtn.addEventListener("click", () => {
    if(num * (Math.floor(cakeListWidth / num) - 1) === $cakeList.scrollLeft) {
        $rightBtn.style.display = 'none';
        $leftBtn.style.display = 'block';
    }
    $cakeList.scrollBy({ left: num, top: 0, behavior: "smooth" });
});

$leftBtn.addEventListener("click", () => {
    if($cakeList.scrollLeft <= num) {
        $leftBtn.style.display = 'none';
        $rightBtn.style.display = 'block';
    }
    $cakeList.scrollBy({ left: -num, top: 0, behavior: "smooth" });
});

2. 버튼 처리

- display

바로위 코드와 같은 코드일때

display를 사용하면 갑자기 요소가 사라져서 이상한곳에 팝업창이 생긴다. 요소는 있으면서 보이지 않는 visibility가 적절할 거 같다.

- visibility

$rightBtn.addEventListener("click", () => {
    $leftBtn.classList.remove('hide');
    console.log($cakeList.scrollLeft);
    console.log(num * (Math.floor(cakeListWidth / num) - 1));
    if(num * (Math.floor(cakeListWidth / num) - 1) === $cakeList.scrollLeft) {
        $rightBtn.classList.add('hide');
    }
    $cakeList.scrollBy({ left: num, top: 0, behavior: "smooth" });
});

$leftBtn.addEventListener("click", () => {
    console.log($cakeList.scrollLeft);
    if($cakeList.scrollLeft <= num) {
        $leftBtn.classList.add('hide');
        $rightBtn.classList.remove('hide');
    }
    $cakeList.scrollBy({ left: -num, top: 0, behavior: "smooth" });
});

이제 안뜬다.

✅내용이 요소의 크기를 벗어났을 때

overflow: hidden을 하면된다. 하지만 바로 바깥의 것을 overflow: hidden처리를 하면 버튼까지 영역을 벗어난 부분에서 보이지 않는다.

그냥 하나 더 감싸주면 된다.

  • 전 html
	<div class="cakes-container">
    	<ul class="cakes-wrap">
              ...
        </ul>
        <div class="cake-info" id="cakeModal">
        	<button class="info-btn" id="cGoToStore"><a>가게 보러 가기</a></button>
            <button class="info-btn" id="cGoToOrder"><a>주문 하러 가기</a></button>
       	</div>
    </div>
    <button class="arrow-btn hide" id="left">
    	<i class="fa-solid fa-angle-left"></i>
    </button>
    <button class="arrow-btn" id="right">
    	<i class="fa-solid fa-angle-right"></i>
	</button>
  • html
<div class="cakes-btn-wrap">
	<div class="cakes-container">
    	<ul class="cakes-wrap">
              ...
        </ul>
        <div class="cake-info" id="cakeModal">
        	<button class="info-btn" id="cGoToStore"><a>가게 보러 가기</a></button>
            <button class="info-btn" id="cGoToOrder"><a>주문 하러 가기</a></button>
       	</div>
    </div>
    <button class="arrow-btn hide" id="left">
    	<i class="fa-solid fa-angle-left"></i>
    </button>
    <button class="arrow-btn" id="right">
    	<i class="fa-solid fa-angle-right"></i>
	</button>
</div>
  • css
.cake-btn-wrap {
    position: relative;
    width: 940px;
    position: relative;
    margin: 0 auto;
}

.cakes-container {
    width: 940px;
    position: relative;
    margin: 0 auto;
    overflow: hidden;
}

.cakes-wrap {
    display: flex;
    width: 940px;
    list-style: none;
    padding: 0;
    white-space: nowrap;
    overflow-x: scroll;
    -ms-overflow-style: none;
    /* IE, Edge */
    scrollbar-width: none;
    position: relative;
    margin: 0;
    padding: 16px 0;
}

.cakes-wrap::-webkit-scrollbar {
    display: none;
}

.cakes-wrap li {
    margin-left: 20px;
    cursor: pointer;
}

.cakes-wrap li:nth-child(1) {
    margin-left: 0;
}

.cake-img {
    border-radius: 10px;
    width: 220px;
    height: 220px;
}

.cake-img::nth-child(1) {
    margin-left: 0;
}

.cake-info {
    /* display: flex; */
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 220px;
    height: 220px;
    position: absolute;
    top: 16px;
    border-radius: 10px;
    background-color: rgba(217, 217, 217, 0.8);
    display: none;
}

.info-btn {
    width: 180px;
    height: 40px;
    background-color: transparent;
    border: 0.5px solid black;
    border-radius: 30px;
    font-weight: bold;
    cursor: pointer;
}

.cake-info .info-btn:nth-child(1) {
    margin-bottom: 26px;
}

.arrow-btn {
    position: absolute;
    width: 50px;
    height: 50px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.9);
    cursor: pointer;
    z-index: 10;
}

.arrow-btn#left {
    top: 50%;
    left: 0px;
    transform: translate(-50%, -50%);
}

참고:
https://velog.io/@kkaemi/css-javascript-display-visibility%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EC%9A%94%EC%86%8C-%EC%88%A8%EA%B8%B0%EA%B8%B0-%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0

0개의 댓글