프론트엔드/컴포넌트

부드러운 가로 스크롤링

syleemomo 2023. 6. 27. 06:45
728x90

https://webty.tistory.com/178

 

JS : 스크롤 동적처리 1. scrollTo, scrollBy, offsetTop, scroll-behavior

window.scrollTo( X, Y ) window.scrollTo({ X좌표, Y좌표 }) 문서의 지정된 위치로 스크롤을 이동합니다. * X, Y좌표는 문서의 왼쪽 상단부터 시작합니다. * X, Y좌표는 px 단위의 가로/세로 축입니다. * X 좌표의

webty.tistory.com

 

https://www.javascripttutorial.net/javascript-dom/javascript-width-height/

 

Getting Width & Height of an Element in JavaScript

In this tutorial, you will learn how to get the current computed dimension of an element, including width and height, in JavaScript.

www.javascripttutorial.net

 

https://mong-blog.tistory.com/entry/JS-%EC%B5%9C%EB%8C%80-%EC%8A%A4%ED%81%AC%EB%A1%A4%EA%B0%92-%EA%B5%AC%ED%95%98%EB%8A%94-%EB%B2%95scrollTop-scrollLeft

 

[JS] 최대 스크롤값 구하는 법(scrollTop, scrollLeft)

이번 시간에는 scrollTop, scrollLeft에 대해 알아보고, 최대 스크롤 값을 구하는 방법을 알아보자 최대 스크롤값 구하는 방법을 알고 싶다면 2.로 바로 이동하자 1. scrollTop, scrollLeft는 무엇일까? 1) scrol

mong-blog.tistory.com

https://stackoverflow.com/questions/6338217/get-a-css-value-with-javascript

 

Get a CSS value with JavaScript

I know I can set a CSS value through JavaScript such as: document.getElementById('image_1').style.top = '100px'; But, can I get a current specific style value? I've read where I can get the entire

stackoverflow.com

 

 

기본적인 아이디어는 현재 컨테이너 너비를 아이템 너비로 나눠서 현재 컨테이너에 몇개의 아이템(갯수)이 보이는지 알아낸다. 이전과 다음 버튼을 클릭했을때 현재 위치(currentPosition)에서 보이는 갯수만큼 더하거나 빼준다. 현재 위치에 있는 요소로 스크롤한다. box-sizing: border-box 로 설정해서 패딩과 보더는 width 안에 포함되도록 하면 계산이 편하다. 마진만 신경쓰면 되는데 마진은 자바스크립트로 css 에 설정된 값이 얼마인지 가져올 수 있다. 아이템 너비로 나눠줄때 아이템 너비에 마진도 포함한다. 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Slideshow</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="wrapper">
        <div class="container">
            <div class="item"><a href="#">1 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">2 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">3 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">4 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">5 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">6 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">7 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">8 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">9 - Lorem ipsum dolor sit amet consectetur</a></div>
            <div class="item"><a href="#">10 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">11 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">12 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">13 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">14 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">15 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">16 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">17 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">18 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">19 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">20 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">21 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">22 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">23 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">24 - Lorem ipsum dolor sit amet consectetu</a></div>
            <div class="item"><a href="#">25 - Lorem ipsum dolor sit amet consectetu</a></div>
        </div>
        <div class="actions">
            <button><</button>
            <button>></button>
        </div>
    </div>
    <script>
        let currentPosition = null 
        const container = document.querySelector('.container')
        const item = document.querySelector('.container .item')
        const btns = document.querySelectorAll('.actions button')
        const numOfItems = document.querySelectorAll('.container .item').length
        console.log(numOfItems)
        
        // get margin of item 
        const style = window.getComputedStyle(item)
        const itemMargin = parseInt(style.getPropertyValue('margin'))
        console.log(itemMargin)

        btns[0].addEventListener('click', function(){
            console.log('container:', container.getBoundingClientRect())
            console.log('item:', item.getBoundingClientRect())
            const containerWidth = container.getBoundingClientRect().width
            const itemWidth = item.getBoundingClientRect().width

            const numOfItemsToMove = Math.floor(containerWidth / (itemWidth + 2 * itemMargin))
            if(currentPosition >= numOfItemsToMove) currentPosition -= numOfItemsToMove
            console.log(currentPosition)
            const elementToScroll = document.querySelectorAll('.container .item')[currentPosition]
            if(elementToScroll) elementToScroll.scrollIntoView({ behavior: 'smooth', inline: 'start' })
        })
        btns[1].addEventListener('click', function(){
            console.log('container:', container.getBoundingClientRect())
            console.log('item:', item.getBoundingClientRect())
            const containerWidth = container.getBoundingClientRect().width
            const itemWidth = item.getBoundingClientRect().width

            // scrollBy 는 정확도가 좀 떨어짐
            // const numOfItems = Math.floor(containerWidth / itemWidth)
            // console.log(numOfItems)
            // container.scrollBy({ left: numOfItems * itemWidth, behavior: 'smooth' })

            // const orderToScroll = Math.floor(containerWidth / itemWidth)
            // console.log(orderToScroll)
            // const elementToScroll = document.querySelectorAll('.container .item')[orderToScroll*cnt]
            // if(elementToScroll) elementToScroll.scrollIntoView({ behavior: 'smooth', inline: 'start' })

            const numOfItemsToMove = Math.floor(containerWidth / (itemWidth + 2 * itemMargin))
            if(currentPosition < numOfItems - 1) currentPosition += numOfItemsToMove
            console.log(currentPosition)
            const elementToScroll = document.querySelectorAll('.container .item')[currentPosition]
            if(elementToScroll) elementToScroll.scrollIntoView({ behavior: 'smooth', inline: 'start' })



        })
    </script>
  </body>
</html>
*{
  box-sizing: border-box;
}
.wrapper{
  width: 35%;
  position: relative;
  display: inline-block;
}
.container{
  height: 200px;
  border: 3px solid #333;
  display: flex;
  overflow: scroll;
}
.wrapper .actions button{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer;
  width: 30px; height: 30px;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, .3);
  border: none;
}
.wrapper .actions button:nth-child(1){
  left: 5px;
}
.wrapper .actions button:nth-child(2){
  right: 5px; 
}
.wrapper .actions button:hover{
  background-color: rgba(0, 0, 0, .5);
}
.item{
  background-color: #fff; color: #333;
  border: 2px solid #333;
  margin: 10px;  
}
728x90