티스토리 뷰

TIL

[TIL] 구글링과 친해지는 중

yojessie 2022. 3. 23. 01:09

 

여러가지 이유로 한동안 코딩을 놓고 있었다.

어쨌든 틈틈이 이전에 만든 것에 목표한 기능을 추가하는데 성공했고

그러면서 배운 개념들을 복습할겸 대략 정리해 본다.

 


1.  값이 자동으로 계산되는 인풋 만들기

옵션A  와 옵션B 퍼센트 수치를 입력하는 인풋에, 한쪽만 입력해도 나머지가 자동 계산되도록 하는 기능을 추가했다.

const inputPercent = document.querySelectorAll('.input.number');

function calculatePercent() {
  const max = 100;

  if(this.value > max) {
    alert('It must be a number less than 100');
    this.value = 0;
  }

  if(this == inputPercent[0]) {
    inputPercent[1].value = max - inputPercent[0].value;
  } else if(this == inputPercent[1]) {
    inputPercent[0].value = max - inputPercent[1].value;
  }
}

for(let i = 0; i < inputPercent.length; i++) {
  inputPercent[i].addEventListener('input', calculatePercent);
}

 

max 값을 선언해놓고,

if문을 이용해 첫번째 인풋이면 두번째 인풋에, 두번째 인풋이면 첫번째 인풋에 나머지 값이 들어가도록 했다.

max 보다  큰 값이 들어오면 alert도 띄웠다.

 

젤 만만해보여서 이것부터 시작했는데,

이런식으로 뭔가를 만들어보는게 처음이라 어디서부터 어떻게 검색해봐야할지 막막 했던 것 같다.

구글링 자체도 익숙하지 않아서 처음에는 혼자 고민하다가.. 차츰 갖가지 키워드로 검색해보기 시작했다.

당연히 내가 원하는 정답을 그대로 찾을 수는 없었지만, 다른 비슷한 기능의 코드를 보면서 힌트를 얻을 수 있었다.

 

 


2.  인풋에 입력한 값으로 동적 리스트 만들기

비슷한걸 앞에 들었던 강의에서 만들어 봤던지라 기억을 더듬으면 쉽게 할 수 있을 줄 알았는데... 호락호락하지 않았다.

HTML 태그를 가져와서 template로 선언하고

각 인풋의 값을 해당하는 자리에 템플릿 리터럴로 넣었다.

그런다음 li 태그를 생성해 선언하고, 다른 리스트의 구조에 맞게 클래스를 추가했다.

그리고 앞에 만든 템플릿을 li에 innerHTML 하고, ul에 append 해서 이벤트를 걸었다.

const generateButton = document.querySelector('.input-button');

function handleGenerate() {
    const inputTitle = document.querySelector('.input.title');
  const inputOption = document.querySelectorAll('.input.option');
  const ul = document.querySelector('.polls-list');
  const li = document.createElement('li');
  li.classList.add('polls-item');

  let template = `
      <div class="polls-item-title">
        <div class="polls-item-select">
          <button class="check-button"></button>
          <p class="option">${inputOption[0].value}</p>
          <p class="percent hidden">${inputPercent[0].value}%</p>
        </div>
        <h4>${inputTitle.value}</h4>
        <div class="polls-item-select right">
          <button class="check-button"></button>
          <p class="option">${inputOption[1].value}</p>
          <p class="percent hidden">${inputPercent[1].value}%</p>
        </div>
      </div>
      <div class="polls-item-graph">
        <div class="graph-selected hidden">
          <img class="graph-ball" src="./asset/graph-ball.svg" />
        </div>
      </div>`

  li.innerHTML = template;
  ul.appendChild(li);
}
  
generateButton.addEventListener('click', handleGenerate);

 

 

처음에는 li 태그까지 통째로 템플릿에 넣어서 ul에 innerHTML했는데,

그러면 기본으로 HTML에 들어있던 리스트가 템플릿 내용으로 대체되어버렸다.

그래서 JS에서 li를 생성한다음 템플릿에 선언한 태그를 innerHTML하고, li를 다시 ul에 appendChild 해야했다.

 

innerHTML과 appendChild 비교

[javascript] InnerHTML 과 appendChild의 비교Programing/Javascript 2011/07/14 03:46 HTML...

blog.naver.com

 

 


3. 리스트를 생성할때 인풋이 비어있으면 알려주기

처음에는 input을 잡아와서 value가 비어있는것을 if문의 조건으로하면 잡힐줄 알았는데 안되서 한참 걸렸다.

따져가며 생각해보니 input이 여러개이기 때문에, 모든 인풋에 조건문을 대입해 보도록하는 반복문이 필요했다.

  const inputs = document.querySelectorAll('.input');

  for(let i = 0; i < inputs.length; i++) {
    if (inputs[i].value == '') {
      alert('Please fill the inputs');
      return;
    }
  }

그리고 이 코드 뒤에 있는 리스트생성 코드가 실행되지 않도록 return으로 함수의 실행을 종료했다.

 

 

 


4. 리스트 생성 후에 인풋 비워주기

이벤트 함수 마지막에는 리스트 생성 후 인풋을 비워주는 코드도 추가했다.

  for(let i = 0; i < inputs.length; i++) {
    inputs[i].value = '';
  }

 

 


5. 동적으로 생성한 태그에 이벤트 걸기 🤯

젤 오래 걸렸던 부분..

동적으로 생성한 태그에는 이벤트가 걸리지 않는다는 걸 알게됐다.

 

그리고 이 내용은 아무리 검색해도 내 코드 상황에 딱 맞는 예시가 없고, 심플한 코드 예시들만 찾을 수 있었는데..

영어 키워드로 검색하는 쪽이 자료가 훨씬 풍부하다는 것도 깨달았다.

 

event binding / bubbling / capturing / DOM / dynamically created elements 등의 키워드가 필요했다.

잘 모를때 두루뭉술한 키워드에서부터, 진짜 내가 필요한 쪽에 맞는 뾰족한 키워드를 찾아가는 맛이 있다.

 

 

How to Bind Event Listeners to Dynamically-Created Elements in JavaScript

You may have noticed that new elements you dynamically create don't automatically have the event listeners that its peers have. Here's how to make sure they have those listeners.

typeofnan.dev

 

동적 생성 요소에 영향을 받지 않는 부모에게 이벤트를 걸었고, 이벤트 리스너에는 캡쳐링을 위한 true 옵션을 추가했다.

이벤트가 일어난 대상이 내가 원하는 자식요소의 클래스를 포함하는지 확인하는 if문을 만들었는데,

아무리 많은 문서를 보고 시도해봐도 해결이 안되었다.

 

 

그리고 드디어 찾아낸것은... this 와 event.target이 다르다는 사실... 😳

 

Bubbling and capturing

 

javascript.info

 

이 문서에 대해서는 다시 한번 정리해서 포스팅해봐야겠다.

 

 

무튼 며칠동안 끙끙대며 고민하던 것이 이렇게 툭 풀렸을때의 쾌감!! 진짜 너무 좋다!

const section = document.querySelector('.polls');

function pollsAnimation(event) {

  if(event.target.classList.contains('button-svg')) {
    
    event.target.closest('.check-button').classList.add('button-active');
    event.target.querySelector('path').classList.add('button-active-svg');
  
    const pollsItem = event.target.closest('.polls-item');
    const selectedSide = event.target.closest('.polls-item-select');
    const selectedGraph = pollsItem.querySelector('.graph-selected');
    const percent = selectedSide.querySelector('.percent').innerText;
    
    if (selectedSide.classList.contains('right')) {
      pollsItem.classList.add('selected', 'right');
    } else {
      pollsItem.classList.add('selected');
    }
    
    setTimeout(function() {
      selectedGraph.style.width = percent;
    }, 200);
  }

}

section.addEventListener('click', pollsAnimation, true);

 

 

 

 

이렇게 결국 추가하고자 했던 모든 기능을 추가했다.

이제 드뎌 버그님 강의 마무리하러 가야징 🥳

 

 

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함