#TIL_21.08.22

ISOJ·2021년 8월 22일
0

Today I Learned

목록 보기
12/43
post-thumbnail

토글 버튼 만들기

  • 명령형 방식
// 버튼생성. (메모리 상에만 생성 ... 화면에 그리지는 않음)
const $button = document.createElement('button')
$button.textContent = 'Button'

// 만든 버튼을 화면에 그린다. (눌렀을 때 반응은 없음)
const $main = document.querySelector('#app')
$main.appendChild($button)

// 버튼을 클릭하면 삭선이 그어진다.
if ($button.style.textDecoration === 'line-through') {
  $button.style.textDecoration = 'none'
}
else {
  $button.style.textDecoration = 'line-through'
}

// querySelectorAll 을 통에 화면에 그려지는 button 을 전부 가져옴
document.querySelectorAll('button').forEach($button => {
  $button.addEventListener('click', (e) => {
    const { target } = e
    toggleButton(target)
  })
})

위 방법은 버튼을 추가하거나 했을 때, 구문들이 늘어나면서 코드 작동 예측이 힘들어짐.

토글 버튼의 기능이나, 화면의 동작을 하나로 묶어 독립작인 형태로 만들어 주는게 좋다.

  • ToggleButton 이라는 이름으로 추상화 하는 방법
function ToggleButton({ $target, text }) {
  const $button = document.createElement('button')
  let isInit = false
  
  this.render = () => {
    $button.textContent = text
    
    if (!isInit) {
      $target.appendChild($button)

      $button.addEventListener('click', () => {
        if ($button.style.textDecoration === 'line-through') {
          $button.style.textDecoration = ''
        }
        else {
          $button.style.textDecoration = 'line-through'
        }
      })
      isInit = true
    }
  }
  this.render()
}

위 방법은 기능 추가와 확장 등이 굉장히 쉬워짐.

3번 클릭할 때 마다 alert

let clickCount = 0

this.render = () => {
// ...
$button.addEventListener('click', () => {
  clickCount++
  // ...
  if (onClick) {
    onClick(clickCount)
  }
}


new ToggleButton({
  $target: $app,
  text: 'Button',
  onClick: (clickCount) => {
    if (clickCount % 3 === 0) {
      alert('세번째 클릭!')
    }
  }
})

ToggleButton 외에 5초 뒤에 자동 토글되는 버튼 만들기

function TimerButton({ $target, text, timer = 3000, onClick }) {
  const button = new ToggleButton({ $target, text, onClick: () => {
    setTimeout(() => {
      button.setState({
        ...button.state,
        toggled: !button.state.toggled
      })
    }, timer)
  }})
}

new TimerButton({
  $target: $app,
  text: '10초 뒤에 자동으로!',
  timer: 1000 * 10
})

회고

선언형의 사고방식이 아직 많이 어려운 부분인 것 같다. 프레임워크를 다루려면 얼른 익숙해져야 할탠데, 아직은 확실히 명령형에 많이 익숙하다.

중간중간 멈춰두고 흐름을 따라가는데 아직은 이해가 바로바로 오지 않는 부분들이 있어서 계속계속 눈에 익히며 공부하려고 한다.

앞으로 강의가 쭉 선언형 방식으로 컴포넌트화 하여 진행될 것 같은데, 보다보면 익숙해질지.. 따로 챙겨 추가로 공부할 수 있는 좋은 방법이 뭐가 있을지 고민해봐야겠다.

profile
프론트엔드

0개의 댓글