-
JavaScript 입문 : 우클릭 이벤트 - contextmenu, 우클릭 이벤트를 통한 깃발과 물음표 만들기컴퓨터 알아가기/JavaScript 2022. 10. 30. 19:30728x90반응형
지금까지 마우스 좌클릭을 통해 클릭이벤트를 공부는 해보았지만 우측클릭으로 하는 경우는 이번이 처음 배워보는 것 같습니다.
보통 addEventListener를 사용하는 경우 좌클릭 이베트는 'click'이었는데 우클릭은 'contextmenu'라는 이벤트가 따로 있습니다.
지금 이 글을 쓰고 있는 화면에 우측클릭을 해보면 다음과 같이 나옵니다.
상기 그림과 같이 우측클릭을 하면 나오는 내용을 제어하고 만들 수 있는이벤트가 contextmenu입니다.
지금부터는 contextmenu를 통해 10 X 10 배열칸에 우클릭을 통하여 깃발이나 물음표를 표시하는 기능을 배워보도록 할 예쩡입니다.
이는 제로초 TV 지바스크립트 강좌를 통하여 공부를 하고 있습니다.
▒ 우클릭이벤트
1. 우클릭이벤트로 만들어야 할 것
순서도를 기억해 보면 우클릭으로 깃발이나 물음표를 만들 예정입니다. 열린칸인지 아닌지를 판단하고 물음표를 표시할지 아니면 깃발을 표시할지 게임을 진행하면서 판단할 수 있는 기능을 만들어 주는게 기본 방향입니다. 물론 다시 닫힌칸으로 만드는 원상복귀까지 고려해야 할 듯 합니다.
2. 우클릭이벤트 선언
지뢰모양이 나온 data에 같이 연결을 해줘야합니다. 각 칸을 나타내는 <td>태그인 target이 해당되는데 100칸에 전부 연결을 해주면 나중에 우클릭이벤트를 해지할때도 100칸에 전부 적용을 해줘야하는 번거로움이 있습니다.
이를 해결하기 위하여 이벤트버블링 원칙으로 자식태그와 부모태그가 서로 연결이 되는 원리를 이용하여 <tbody>태그에 우클릭이벤트를 연결합니다.
3. 우클릭을 통한 물음표와 깃발 만들기
우리가 처음 만든 코드숫자 구분에서 물음표와 깃발에 대한 코드를 다음과 같이 만든적이 있습니다. 이 중에 물음표와 깃발은 다음 코드숫자가 필요하겠죠.
또 필요한 사항은 각 이벤트가 일어나는 <td>태그를 변수에 저장하고 각 데이터를 가져올 수 있는 코드를 각 코드숫자와 연결시키는 작업이 필요합니다.
역시 사전에 data라는 광역변수를 선언해 주었기때문에 편의상 data를 이용합니다.
// 6.1 onRightclick() function onRightClick(e) { e.preventDefault(); // 우클릭 기본기능 삭제 const target = e.target; // 몇번째 칸 클릭했는지 알기위해 row와 cell 변수 const rowIndex = target.parentNode.rowIndex; // tr const cellIndex = target.cellIndex; const cellData = data[rowIndex][cellIndex]; // data 변수 선언필요 if (cellData === CODE.MINE) { // 지뢰면 물음표지뢰로 data[rowIndex][cellIndex] = CODE.QUESTION_MINE; // data에 직접 입력 target.className = 'question'; target.textContent = '?'; } else if (cellData === CODE.QUESTION_MINE) { // 물음표지뢰면 깃발지뢰로 data[rowIndex][cellIndex] = CODE.FLAG_MINE; target.className = 'flag'; target.textContent = '!'; } else if (cellData === CODE.FLAG_MINE) { // 깃발지뢰면 지뢰로 data[rowIndex][cellIndex] = CODE.MINE; target.className = ''; target.textContent = 'X'; } else if (cellData === CODE.NORMAL) { // 일반사항이면 물음표로 data[rowIndex][cellIndex] = CODE.QUESTION; target.className = 'question'; target.textContent = '?'; } else if (cellData === CODE.QUESTION) { // 물음표면 깃발로 data[rowIndex][cellIndex] = CODE.FLAG; target.className = 'flag'; target.textContent = '!'; } else if (cellData === CODE.FLAG) { // 깃발이면 일반사항으로 data[rowIndex][cellIndex] = CODE.NORMAL; target.className = ''; target.textContent = ''; } }
이제 브라우저를 보게되면 우클릭으로 지뢰가 숨겨져 있다고 예상되는 칸에 물음표나 깃발 또는 원상태로 복귀시킬 수 있는 기능을 볼 수 있습니다.
현재까지 진행된 자바스크립트 코드는 다음과 같습니다.// 1. HTML 활성화 (자바스크립트로 연결) const $timer = document.querySelector('#timer'); const $tbody = document.querySelector('#table tbody'); // tr, td가 기입예정 const $result = document.querySelector('#result'); // 2. 가로 세로 지뢰의 수 const row = 10; // 줄 const cell = 10; // 칸 const mine = 10; // 지뢰 // 3. 종류에 대한 코드명과 코드숫자 넣기 const CODE = { NORMAL: -1, // 닫힌칸 (지뢰없음) QUESTION: -2, // 물음표칸 (지뢰없음) FLAG: -3, // 깃발칸 (지뢰없음) QUESTION_MINE: -4, // 물음표칸 (지뢰있음) FLAG_MINE: -5, // 깃발칸 (지뢰있음) MINE: -6, // 닫힌칸 (지뢰있음) OPENED: 0, // 열린칸, 0이상이면 (8까지) 모두 열린칸 } // 4. 변수 묶기 let data; // 5. 게임의 흐름 // 5.3 function plantMine() { // 10 X 10 테이블 각각 칸을 위한 인덱스 만들기 const candidate = Array(row * cell).fill().map((e, i) => { return i; }); console.log(candidate); // 지뢰에 연결할 랜덤 10개 뽑기 const shuffle = []; for (let i = 0; i < mine; i++) { const random = Math.floor(Math.random() * candidate.length); const choice = candidate.splice(random, 1)[0]; shuffle.push(choice); } console.log(shuffle); // 100개의 칸 NORMAL 코드 심기 const data = []; // data에 최종 지뢰심기 for (let i = 0; i < row; i++ ) { const normal = []; data.push(normal); for (j = 0; j < cell; j++) { normal.push(CODE.NORMAL); } } console.log(data); // 10개의 칸 MINE 코드 심기 for (k = 0; k < shuffle.length; k++) { const rowTen = Math.floor(shuffle[k] / row); // 2 const cellOne = shuffle[k] % cell; // 2 data[rowTen][cellOne] = CODE.MINE; } return data; console.log(data); } // 6.1 onRightclick() function onRightClick(e) { e.preventDefault(); // 우클릭 기본기능 삭제 const target = e.target; // 몇번째 칸 클릭했는지 알기위해 row와 cell 변수 const rowIndex = target.parentNode.rowIndex; // tr const cellIndex = target.cellIndex; const cellData = data[rowIndex][cellIndex]; // data 변수 선언필요 if (cellData === CODE.MINE) { // 지뢰면 물음표지뢰로 data[rowIndex][cellIndex] = CODE.QUESTION_MINE; // data에 직접 입력 target.className = 'question'; target.textContent = '?'; } else if (cellData === CODE.QUESTION_MINE) { // 물음표지뢰면 깃발지뢰로 data[rowIndex][cellIndex] = CODE.FLAG_MINE; target.className = 'flag'; target.textContent = '!'; } else if (cellData === CODE.FLAG_MINE) { // 깃발지뢰면 지뢰로 data[rowIndex][cellIndex] = CODE.MINE; target.className = ''; target.textContent = 'X'; } else if (cellData === CODE.NORMAL) { // 일반사항이면 물음표로 data[rowIndex][cellIndex] = CODE.QUESTION; target.className = 'question'; target.textContent = '?'; } else if (cellData === CODE.QUESTION) { // 물음표면 깃발로 data[rowIndex][cellIndex] = CODE.FLAG; target.className = 'flag'; target.textContent = '!'; } else if (cellData === CODE.FLAG) { // 깃발이면 일반사항으로 data[rowIndex][cellIndex] = CODE.NORMAL; target.className = ''; target.textContent = ''; } } // 5.2 function startGame() { data = plantMine(); // data와 연결하는 tr, td 화면 만들고 지뢰 연결 data.forEach((row) => { // row부터 const $tr = document.createElement('tr'); row.forEach((cell) => { const $td = document.createElement('td'); if (cell === CODE.MINE) { $td.textContent = 'X'; } $tr.append($td); }); $tbody.append($tr); // 6. 우클릭이벤트 $tbody.addEventListener('contextmenu', onRightClick); }); } startGame(); // 5.1
참고로 브라우저상에는 다음과 같이 코드숫자가 잘 반영이 되고 있는지 확인할 수 있습니다.
반응형'컴퓨터 알아가기 > JavaScript' 카테고리의 다른 글
JavaScript 입문 : 지뢰찾기 게임 - 주변지뢰 갯수 찾기(카운트)와 Optional Chaining (0) 2022.11.01 JavaScript 입문 : 좌클릭 이벤트 - 지뢰를 클릭하면 게임종료 및 일반칸 클릭시 논리적으로 주변 지뢰갯수 세는 방법 고민 (0) 2022.10.31 JavaScript 입문 : 논리연산자 AND (&&) 와 OR (||) (0) 2022.10.27 JavaScript 입문 : 지뢰찾기 게임 - 본격적인 지뢰심기 (0) 2022.10.26 JavaScript 입문 : 지뢰찾기 게임 - 기본적 HTML / CSS 만들기, 지뢰를 심기위한 랜덤숫자 뽑기 (0) 2022.10.25