[JS] PingPongScoreKeeper 만들며 몰랐던 점

2023. 3. 2. 23:27Trip to Front-end

1. HTML

- bulma에 대해 새롭게 배웠다.

> 부트스트랩봐 표현법이 더 직관적이어서 좋았다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
  <title>Ping Pong Score Keeper</title>
  
</head>
<body>

  <!-- 5. 스타일을 넣기 위한 벌마~ -->
  <section style="margin: 50px">
    <div class="container">
      <div class="columns">
        <div class="column is-half is-offset-one-quarter">
          <div class="card">
            <div class="card-image">
              <figure class="image is-7by3">
                <img src="https://images.unsplash.com/photo-1534158914592-062992fbe900?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3784&q=80" alt="">
              </figure>
            </div>
            <header class="card-header">
              <p class="card-header-title">
                Ping Pong Score Keeper
              </p>
              <button class="card-header-icon" aria-label="more options">
                <span class="icon">
                  <i class="fas fa-angle-down" aria-hidden="true"></i>
                </span>
              </button>
            </header>
            <div class="card-content">
              <div class="content">
                <h1 class="title is-1"><span id="p1Display">0</span> to <span id="p2Display">0</span></h1>
                <p class="subtitle">Use the buttons below to keep score</p>
                <label for="setScore" class="label is-large is-inline">Playing to</label>
                <div class="select is-rounded">
                  <select name="" id="setScore">
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                    <option value="6">6</option>
                    <option value="7">7</option>
                    <option value="8">8</option>
                    <option value="9">9</option>
                    <option value="10">10</option>
                    <option value="11">11</option>
                  </select>
              </div>
              </div>
            </div>
            <footer class="card-footer">
              <button class="button is-primary card-footer-item" id="p1Btn">+1 Player One</button>
              <button class="button is-info card-footer-item" id="p2Btn">+2 Player Two</button>
              <button class="button is-danger card-footer-item" id="reset">Reset</button>
            </footer>
          </div>
        </div>
      </div>
    </div>
</section>


  
<!-- 4번의 일환으로 select만들기 -->
  <script src="app1.js"></script>

</body>
</html>

2. JS

- innerHTML, innerText, textContent의 차이를 몰랐다.

>  innerText의 경우 불필요한 공백은 제거하고 브라우저 상에 출력되는 값을 그대로 가져온다. 만약 html 상 입력은 되었는데 브라우저의 display:none;으로 보여지지 않는다면 결과도 보여지지 않는다.

> textContent를 알기 전에 노드라는 개념을 알고 있어야하는데 html의 계층적 구조와 속성을 말해주는 것이다. 예를들어 

h1같은 태그는 노드, a 태그의 href는 속성 노드, 그 안의 텍스트는 텍스트 노드이다.

 > textContent의 경우 mdn 문서 캡쳐로 대체한다. 

> 여기서 궁금증은 마지막 reset 함수에서 innerText는 안되는지 였다.

const p1 = {
  score: 0,
  button: document.querySelector('#p1Btn'),
  display: document.querySelector('#p1Display')
}

const p2 = {
  score: 0,
  button: document.querySelector('#p2Btn'),
  display: document.querySelector('#p2Display')

}

const resetBtn = document.querySelector('#reset')
const setScore = document.querySelector('#setScore')


let winningScore = 3;
let isGameOver = false;

// 1. 먼저 버튼을 눌렀을 때 점수가 오른다.
// 여기서 질문 왜 이렇게 바로 display 값을 변경하는게 안되는가? 선택의 의미만 갖는다. 그리고 textContent와 innerText의 차이


function updateScores(player, opponent) {
  if (!isGameOver) {
    player.score += 1;
    if (player.score === winningScore) {
      isGameOver = true;
      player.display.classList.add('has-text-success')
      opponent.display.classList.add('has-text-danger')
      player.button.disabled = true;
      opponent.button.disabled = true;
    } 
      player.display.textContent = player.score;
  }
}


p1.button.addEventListener('click', function() {
  // 3. 설정한 점수까지만 올라간다. 설정하기
  // 4. winningScore가 상수가 아니라 변수로 설정해야한다는 것 
  updateScores(p1, p2)
})
  

p2.button.addEventListener('click', function() {
  updateScores(p2, p1)
})

//  4. 셀렉트 값을 받아서 위닝스코어하고 연동 
//  여기서 문제는 내가 스트링인데 숫자로 생각해서 안되었다. 숫자로 바꿔주어야함 싶할~
setScore.addEventListener('change', function() {
  winningScore = parseInt(this.value);
  reset();
})

// 2. 리셋 버튼은 초기화

resetBtn.addEventListener('click', reset)
  

function reset() {
  isGameOver = false;
  for (let p of [p1, p2]) {
    p.score = 0;
    p.display.textContent = 0;
    p.display.classList.remove('has-text-success', 'has-text-danger')
    p.button.disabled = false;
  }
}