본문 바로가기
카테고리 없음

[RummiKub/JS] 버튼 조작 구현

by M개발자 2021. 11. 19.
반응형

구현할 버튼

skip turn 해당 턴 건너뛰기 / 타일 한 장 추가
turn refresh 새로고침 / 메인 보드에 있던 타일을 다시 플레이어 보드로 이동
pass 통과


결과물


HTML

버튼 위치 board-body div > board-body-btn div
main-body-before-btn > skip turn btn 해당 턴에서 메인 보드에 추가한 타일이 없을 경우 / default 버튼
main-body-after-btn > refresh btn 해당 턴에서 메인 보드에 추가한 타일이 있는데, 추가 전 상태로 돌아갈 경우
main-body-after-btn > pass btn 해당 턴에서 메인 보드에 추가한 타일이 있고, 그 타일의 묶음이 조건을 만족할 경우

 <div class="board-body"> <div class="main-board"> <div class="set-board" onclick="set_board_click()"> <img src="/image/set.svg" class="tile-set" id="tile-set"> </div> </div> <div class="board-body-btn main-body-before-btn"> <button class="btn main-before-btn" onclick="skip_turn_click()">skip turn</button> </div> <div class="board-body-btn main-body-after-btn"> <button class="btn main-after-btn" onclick="refresh_click()">turn refresh</button><br> <button class="btn main-after-btn" onclick="pass_click()">pass</button> </div> </div>

CSS

해당 턴에서 메인 보드에 타일 등록 전일 경우에는 main-body-before-btn div만 보여야하므로
main-body-after-btn div는 display 속성을 none으로 줘 자리차지도 하지 않게 해주었다.
버튼 css

.btn{ margin: 0; margin-left: 20px; margin-top: 10px; margin-bottom: 10px; width: 100px; } .main-before-btn{ margin-top: 0; height: 360px; } .main-after-btn{ height: 160px; } .player-btn{ height: 100px; } .btn:hover{ cursor: pointer; } .main-body-after-btn{ display: none; }

JS

1. 메인 보드 타일 추가 시 버튼 변경

skip turn만 띄워진 상태였지만, 타일 추가 시 초기화와 추가 버튼으로 바꿔준다.
조건 체크를 위해 메인 보드에 타일 추가할 div에 class를 임시로 추가한다.

add-tile class 임시 추가

function set_board_click() { const setIsPass = isPass(); const mainBoard = document.querySelector('.main-board'); let div = document.createElement("div"); if(setIsPass){ div.className = 'main-board-set-pass'; div.className += ' add-tile'; // 추가 코드 } else{ div.className = 'main-board-set-fail'; div.className += ' add-tile'; // 추가 코드 } ... }

html 코드에서 add-tile 클래스가 있는지 확인하고 있다면 버튼을 교체한다.

// 버튼 div 선언 const beforeBtn = document.querySelector(".main-body-before-btn"); const afterBtn = document.querySelector(".main-body-after-btn"); // 메인 보드에 등록 시 버튼 변경 (skip turn -> 초기화/등록) function hasChildMainBoard(){ // add-tile 클래스가 있는지 찾는다, querySelector는 태그를 못 찾을 경우 null 반환함 if(document.querySelector(".add-tile") != null){ // null이 아니라면 메인 보드에 타일이 추가되었다는 의미로, // skip turn이 포함된 before div의 display 속성을 none (안보이게) // 초기화와 등록이 포함된 after div의 display 속성을 block로 해 버튼을 교체시켜줌 beforeBtn.style.display = 'none'; afterBtn.style.display = 'block'; } }
타일이 추가되면 버튼이 바뀜

2. skip turn click

function skip_turn_click(){ console.log("남은 타일의 마지막 인덱스 ", remainTile[remainTile.length - 1]); // 타일 푸쉬 // 나눠주고 남은 타일이 저장된 remainTile을 pop할 경우 마지막 타일이 반환되고 삭제된다. // 반환된 인덱스를 playerTile에 추가한다. console.log(playerTile.push(remainTile.pop())); console.log("추가된 타일 ", playerTile[playerTile.length - 1]); // player 보드의 타일을 다시 교체해주는 함수 (이전에 선언한 함수임) player_tile_refresh(); }

pop전 remainTile의 마지막 인덱스의 정보와 push된 playerTile의 마지막 인덱스의 정보가 일치하고,
노란색 4가 추가된 걸 확인할 수 있다.

3. refresh click

메인 보드에 타일 추가 시 clickTile에 선택한 타일을 추가했다.
하지만 clickTile은 선택될 때만 유효하고 메인보드에 등록되면 빈 배열이 되어버린다.
그래서 메인 보드에 추가된 타일을 담은 새로운 배열을 따로 선언하였다.

const clickTile = []; const nowTurnTile = []; // 추가 코드 ... function player_tile_click(id) { // alert(id); const tileInfo = playerTile.findIndex((e) => { return e.id == id; }); const tile = document.getElementById(id); if (!tile.classList.contains('tile-click')) { clickTile.push(playerTile[tileInfo]); nowTurnTile.push(playerTile[tileInfo]); // 추가 코드 } ... }


초기화 버튼을 누르면 새로 선언했던 배열 nowTurnTile에 담긴 타일들을 다시 playerTile 배열에 추가하고,
메인 보드에 추가된 div를 제거한다.
그리고 현재 턴에서 메인 보드에 추가된 타일이 없기 때문에 skip turn 버튼이 다시 block 된다.

function refresh_click(){ // 메인 보드에 추가된 타일 수만큼 반복 for(let i = 0; i < nowTurnTile.length; i++){ // pop하여 넣어도 좋지만 플레이어 타일에 거꾸로 들어가서 // 예쁘지 않아 0번째부터 차례대로 추가했다. playerTile.push(nowTurnTile[i]); console.log("플레이어 타일에 다시 추가 ", playerTile[playerTile.length - 1]); } // add-tile 클래스를 찾을 수 없을 때까지 반복 while(document.querySelector('.add-tile') != null){ // add-tile 태그 삭제 document.querySelector('.add-tile').remove(); } // 플레이어 보드 새로고침 player_tile_refresh(); // 현재 턴에서 메인 보드에 추가된 타일이 없으므로 skip turn 버튼을 띄운다. beforeBtn.style.display = 'block'; afterBtn.style.display = 'none'; // 배열 비우기 nowTurnTile.length = 0; }

첫번째 이미지에서 clickTIle은 비어있지만 nowTurnTile은 3개의 요소가 있는 걸 확인할 수 있다.
두번째 이미지는 버튼을 누른 후이다. 추가했던 타일이 다시 플레이어 보드에 들어가고 플레이어 타일 배열에 푸쉬된걸 확인할 수 있다.

4. pass click

function pass_click(){ // add-tile을 포함한 태그의 클래스 확인 // const tile = document.querySelector('.add-tile'); // console.log(tile); // 조건이 일치한 타일 묶음이 있어도 상관없이 조건이 일치하지 않은 타일 묶음이 있다면 함수를 종료시킨다. if(document.querySelector('.main-board-set-fail')){ alert("조건이 일치하지 않습니다."); return; } // pass 클래스가 있다면 조건이 일치하는 태그이다. if(document.querySelector('.main-board-set-pass')){ const tile = document.querySelector('.add-tile'); // 드디어 임시 추가한 태그를 제거해준다. tile.classList.remove('add-tile'); } // 만약을 위해 추가해둔 코드 / 위에서 다 조건 체크되어 여기까지 올 일은 없을 거 같다. else{ alert("조건이 일치하지 않습니다."); return; } // 타일이 추가되었으므로 default 상태로 바꿔준다. beforeBtn.style.display = 'block'; afterBtn.style.display = 'none'; // 배열 초기화 nowTurnTile.length = 0; }
코드의 윗부분 주석 처리된 부분을 해제해보면 로그를 확인할 수 있다.

첫번째 로그는 조건이 일치하는 태그로 div의 클래스를 보면 add-tile 클래스가 없는 걸 확인할 수 있다.
두번째 로그는 조건이 일치하지 않는 태그로 div의 클래스에 아직 add-tile이 있는 걸 확인할 수 있다.


My GitHub
Notion

반응형

댓글