본문 바로가기

Intro/Daily Study Note

[220721] Daily Study Note

 

  Today's Plan  

Studying JavaScript knowledge   

(1) 브라우저 이벤트 소개

(2) 버블링과 캡처링

(3) 이벤트 위임

(4) 브라우저 기본 동작

(5) 커스텀 이벤트 디스패치

 

Coding JavaScript   

(1) Javascript Hangman Game Project 복기

(2) Javascript Tic Tac Toe game project

(3) 깃허브에 업로드하고 내용 정리 

 

Training Coding Test with Python  

(1) 삼성 코딩 테스트 기출 4문제

(2) 코딩 테스트 풀이 정리하고 다른 사람들 풀이까지 이해. 다시 풀면 맞출 정도로

 

9 : 26pm 

못 한 것.

1. 틱탯토 게임 완성.

2. 코테 풀이

3. 자스 개념 절반

: 1, 2는 하고 잘 수 있을 것 같은데 새벽에 수영 때문에 3은 내일 오전으로 넘길 것 같다.

 


1.

https://ko.javascript.info/

 

모던 JavaScript 튜토리얼

 

ko.javascript.info

 

이벤트 기초

2.1 브라우저 이벤트 소개

이벤트는 무언가 일어났다는 신호이고, 모든 DOM노드는 이벤트를 가질 수 있다.

 

자주 쓰이는 이벤트

1. 마우스 이벤트 : click, contextmenu, moseover, mouseout, mouseup, mousedown, mousemove

2. 폼 요소 이벤트: submit, focus

3. 키보드이벤트: keydown, keyup

4. 문서 이벤트: DomContentLoaded

5. CSS 이벤트: transitiones

: 대충만 알아두고 대신 이벤트 발생시키고자 할 때 이런게 있었다고 기억 불러 많이 연습해보기

 

이벤트 핸들러 할당 방식

1. HTML속성

2. DOM 프로퍼티

3. addEventListener

: 내가 이번 주 월요일에 궁금해했던게 1과 2의 차이여서 반갑게 공부했다.

 

1.HTML속성 할당

: HTML의 태그에 on<event> 속성을 할당

: 이 때 주의사항

   (1) [ on<event> : 값 ] 의 값은 큰 따옴표로 묶여야 하고, 그 안에 문자열은 작은 따옴표로 묶여야 제대로 동작한다.

   (2) HTML 속성은 대소문자 구분 안 하긴 하는데 그래도 속성은 거의 소문자로 작성, 그래서 on<event> 도 all소문자로.

 

2. DOM프로퍼티

: DOM 프로퍼티에 on<event>로 할당 가능

// ex
<script>
  elem.onclick = function() {
    /// ...
   };
</script>

 

HTML 속성 할당 동작 방식

1. 핸들러를 HTML 속성 값에 할당하면,

2. 브라우저는 속성값을 이용해 새 함수를 만든다. ( 새 함수 안에 속성값이 들어가는 것. )

3. 그리고 생성된 함수를 다시 DOM프로퍼티에 추가하게 된다.

: 유의 사항

    on<event>는 엘리멘트당 하나의 이벤트 핸들러만 갖는다. 핸들러 뒤늦게 추가하면 처름거 덮어쓴다.

    그래서 이벤트 핸들러 제거 원하면 null을 할당하면 된다.

 

=> 이래서 나온 핸들러에서 자주하는 실수 짚고 가기. (이거 되게 헷갈릴만도 하다.)

DOM Property 방법에서는 함수에 괄호 안 붙이고, HTML속성값은 괄호 붙인다.

 

왜?! ) 브라우저는 속성값을 읽고 속성값은 새 함수를 만들어 한에 속성값을 넣으니까 !

아래의 예시에서 확인 가능.

<button onclick='onclickEventHandler()'></button>

의 onclick 속성은 아래처럼 구현된다.

button.onclick = function(){
    onclickEventHandler();
}

 

그 외 주의사항

(1) setAttribute로 핸들러 할당하지 마라.

document.setAttribute('onclick',function(){alert('click')});

이러면 function(){...} 부분은 문자열 된다.

 

(2) DOM프로퍼티는 대소문자 구별한다. HTML속성이랑 다르다. 헷갈리지 말자.

 

3. addEventListener, removeEventListener

html속성 프로퍼티, DOM프로퍼티의 할당은 복수 메서드 할당이 불가능한 단점 때문에 나온 addEventListener.

element.addEventListener(event, handler, [option]);

으로 사용하고, option값에는

once(true면 한 번만 수행되고 삭제),

capture(어느 단계에서 실행될 지 알려주는 프로퍼티, 이벤트 버블링에서 사용된),

passive(true면 리스너에서 지정한 함수가 preventDefault()를 실행하지 않음)

가 있다.

 

유의.

(1) removeEventListener 사용 시 addEventListener에서 사용한 그 함수 전달해야 한다. 이를 위해서는 변수에 핸들러 지정해놓아야 한다.

왜냐면

elem.addEventListener('click', () => alert('ok'));
ele.removeEventListener('click', ()=> alert('ok'));

요 위레 코드 같이 똑같이 생긴 함수를 지운 것 같지만 사실 둘은 다른 함수객체이므로 제대로 안 지워진다.

function handler() {
    alert('ok');
}
elem.addEventListener('click', handler);
elem.removeEventListener('click', handler);

요렇게 함수 이름으로 똑같은 것에 접근해야 옳다. 

 

(2) 어떤 건 꼭 addEventListener써야하는데, 왜냐면 DOM프로퍼티 접근 불가능할 수 도 있기 때문이었다.

DOMContentLoaded 같은 경우는 말그대로 DOM Tree가 다 셋팅된 후에 실행되는 건데 이런건 DOM프로퍼티로 사용 안 한다. 

 

4. 이벤트 객체

이벤트 프로퍼티 잘 이해해야 이벤트 잘 다룰 수 있는데 이건 연습을 통해서 익히고 외워야 응용과 이해가 좋을 것 같다.

일단 자료에서 빈번하게 사용하는 이벤트 프로퍼티로 제시한 건

event.type, event.currentTarget, event.clientX/event.clientY

사실 내가 사용한 것만 해도 이것보다 많다. 

 

5. 이벤트 핸들러로 함수뿐만 아니라 객체도 할당 가능하다. 물론 클래스도!

자료에서 제시한 클래스로 구현한 핸들러가 참고해서 사용하기 되게 좋다! 재사용성 생각해서 만든 코드라서 꼭 익혀가기.

 

 

 

버블링과 캡처링

제가 자바스크립트에서 참 좋아하는 개념인 이벤트위임과 관련된 기본 개념 내용입니다.

이벤트 실행 흐름을 나타내는 개념들로 설명이 가능하게 정리했습니다.

event.target과 event.currentTarget에서 event.currentTarget을 this와 거의 동일시해서 설명하는게 흥미로웠습니다.

두 프로퍼티의 쓰임은 알고 활용은 했지만, 이론적으로 개념적으로 정리하고 싶었는데 항상 오류 없이 사용해서 그냥 넘어갔습니다. 드디어 말로 풀어 정리하네요. 

 

버블링

한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작한다.그 동작 흐름은 가장 최상위 조상 요소를 만날때까지 거슬러가며 각 핸들러를 동작한다.

 

"거의 모든 이벤트는 버블링된다"고 하는데, 아 안 되는 것도 있긴 있군요. 다음 챕터에서 나온다고 합니다. 재밌겠당!물론 거의 대부분 버블링이 적용된다고 합니다.

 

event.target

부모요소의 핸들러도 이벤트가 정확히 어디서 발생했는지 등에 대한 자세한 정보를 얻을 수 있다고 합니다.즉, 이벤트가 직접적으로 발생한 or 가장 안쪽 요소가 그 타깃 요소입니다.

 

한 번쯤 짚고 넘어가고 싶었던,

event.target과 event.currentTarget의 차이

1) event.target은 실제 이벤트가 시작된 '타깃'요소. 버블링이 진행되며너도 변하지 않습니다. 당연합니다.2) this 는 '현재'요소. 현재 실행 중인 핸들러가 할당된 요소를 참조합니다. ( 이게 내가 분명히 하고 싶었던 개념. 대충 실행은 되는데 이론적으로 흐름을 명확히 하고 싶었습니다.) : 이벤트를 사장 상위에 등록했어도 마찬가지

 

버블링 중단하기

이것도 배운 적 있었는데, 웬만하면 쓰지 말라고 배웠습니다. 자세히 설명해줘서 읭? 했는데, 역시나 사용을 권장하지 않는다고 합니다. 추가적으로 왜 안 되는지에 대한 이유에 대한 설명도 들을 수 있어 좋았습니다.

 

event.stopPropagation & event.stopPropagation

event.stopPropagation() 으로 버블링 중단 가능하다. 해당 메서드는 상위의 버블링을 막지만 다른 핸들러의 동작은 막지 못 한다고 합니다. 이 때 대신 쓸 수 있는 건event.stopImmediatePropagation() : 상위의 버블링도 막고, 할당된 특정 이벤트를 처리하는 핸들러의 동작도 막습니다.: 할당된 특정 이벤트 처리하는  핸들러는 뭘 말하는 건지 안 와닿아서 더 검색해봤습니다.: 아리까리한게 맞았습니다. 동일 단계에서 수행하는 핸들러 중에 본인보다 뒤에 수행되는 핸들러들을 못 하게 하는 것이었습니다.

 

진짜 버블링 멈춰야 하는, 멈춰도 되는 아케텍처 아니면 굳이 멈추지 마라

버블링 멈추는게 안 좋다는 것은 알았지만 왜인지는 몰랐는데, 와닿는 설명을 들을 수 있었습니다.

전체 관점에서 작은 이벤트를 처리하거나 탐지할 수 없어지는 것입니다.

하위 객체의 이벤트가 발생했음이 상위 객체에게 전달이 되어야 상위 레벨에서 통합적으로 그걸 관리할 수 있는데 그게 어려워지는 문제가 있는 것입니다.

 

캡처링

마찬가지로 이전에 학습한 것과 비슷한 내용. 확실히 좋아하는 개념이어서 그런지 다른 자바스크립트 개념 복습해오던 때랑 다르게 재밌게, 잘 기억해내며 복습합니다.

동작과정을 이해하되, 직접적으로 건드릴 일은 실무에선 잘 없더라.

 

정리할만한 건 

이벤트 흐름 3단계

1. 캡처링 단계: 이벤트 발생을 하위로 전파

2. 타깃 단계: 이벤트가 실제 타깃에서 이벤트 트리거

3. 버블링 단계: 이벤트 상위로 전파

 

캡처링을 사용하는 경우는 이벤트의 발생 순서를 알고 싶을 때!

이 때는 앞선 챕터에서 다뤘듯이 addEventListener에 default로는 false로 되어있는 capture 프로퍼티를 true로 주면 된다고 합니다. 이건 몰랐던 정보였습니다. 아하 포인트.

 

그 외에 이벤트 관련 짚고 넘어갈 것.

이벤트 트리거가 동일 레벨, 동일 요소라면 먼저 선언된 것부터 수행된다는 것. 


2.

(1) Javascript Hangman Game Project 복기

 

(2) Javascript Tic Tac Toe game project

프로젝트 안내에서 이런 간단한 게임 같은 경우는 코드를 짜기 전에 로직을 먼저 짜보라, 로직을 플로우 차트로 그려보라.

그래야 코드로 구현하기 좋을 것이다. 라고 안내해서 케이스를 나눠 그림을 그렸습니다.

 

아, 이거 하려고 어제 코딩테스트 구현 문제 풀었나. 싶을만큼 비슷한 동작 방식이어서 헉했습니다.

어제 너무 문제 안 풀리고 어려워서 기 죽어 있었는데 이걸 위한 빌드업이었구나하고 묘한 감정이 들었습니다.

대충 플로우 차트는 그려봤습니다. 코드로 한 번 구현해보겠습니다. 꼭 완성하고 싶어집니다.

 

플로우차트 그리는 것도 해본 적이 있는데, topcit시험 위해서 외우기도 했습니다.UI/UX수업 수강 시에도 사용했습니다.

막상 그리려니 안타깝게도 각 도형의 의미가 기억이 안 납니다. 다시 복습했습니다.

 

 

 

1. [bd9bc3b] | Init: TicTacToe Game App: set content structure and style it"

: HTML, CSS 기본 셋팅 (약 20분) 

: 각 격자를 서로 다른 요소로 만들었습니다.

: 와 이거에 이 시간을 들이다니.. 음 격자판 CSS셋팅하는데서 시간 소요했습니다.

: 아직 flex, float 가 헷갈리는 것 같습니다. 내일 확실히 정리할 것 같습니다.

1차 커밋 초기 셋팅

 

2.  [a50d358] | Feat: TicTacToe Game App: make init popUp with selecting mark function

: PopUp 창을 만들었습니다.

: 유저가 사용할 마크를 클릭하면 팝업이 사라지고, user의 객체에 마크 스타일이 저장되게 했습니다.

 

처음 화면
팝업에서 'X'선택 => 팝업 사라지고 + 유저객체에 'X', 컴퓨터객체에 'O' 저장된다.

 

 

3. [18a16aa] | Feat: TicTacToe Game App: add playComputer function

: 이유는 모르겠지만, 내가 선택했는데 컴퓨터가 우선권을 가집니다. 룰을 그렇게 하자고 했으니 순서를 따라봅니다.

: 컴퓨터의 선택은 빈 칸 중에서 랜덤으로 정해집니다. 해당 기능을 구현합니다.

function playComputer(){
    let num = getRandomNumber(notSelected);
    let selectedGridClass = '.grid'+num;
    let selectedGrid = document.querySelector(selectedGridClass);

    let markingSpan = document.createElement('span');
    markingSpan.textContent = computer['mark'];
    selectedGrid.append(markingSpan);

    notSelected.splice(num, 1);
}
function getRandomNumber(remainNum){
    let num = Math.floor(Math.random()*9);
    if (remainNum.indexOf(num) !== -1){
        return num
    } else {
        return getRandomNumber(remainNum)
    }
}

: 남아 있는 숫자들 중 랜덤으로 숫자를 선택하고 해당 격자판에 마크를 추가합니다.

: 마크는 컴퓨터의 마크사인을 span으로 새 요소를 만들고 그것을 해당 격자에 추가합니다.

: span이 들어올 것을 생각해 CSS 위치 조정을 다시 했습니다.

유저가 'X'사인 한다고 했을 때
유저가 'O'사인 한다고 했을 때

4. [6b54b9e] | Feat: TicTacToe Game App: add playUser function

컴퓨터가 먼저 O를 선택한 후에 유저가 X를 선택한 상황입니다.

function playUser(){
    gameBoard.addEventListener('click', event => {
        if (event.target.tagName === 'DIV'){
            let gridClass = '.'+ event.target.classList[1];
            let num = gridClass.charAt(gridClass.length-1);
            drawMark(gridClass, num, user['mark']);
        }
    })
    return
}

: playUser 함수를 구현했습니다. 다만, 그리는 동작이 playComputer에도 동일하게 나타나 drawMark 라는 함수를 따로 만들어서 빼줬습니다.

: git commit을 할 때 분명 각 커밋당 한 기능만 넣으라고 배웠는데 아직 설계에 맞게 코드를 짜는 형편이 아니어서 playUser 만들다가 drawMark 새로 만들고 playComputer도 손보고, 그에 맞게 css도 다시 고치고 하는 등 여러 수정사항을 한 커밋에 묶어버렸습니다.
: 좋은 개발자로써 해야 한다고 배운 사항들을 실제적으로 적용하려면 정말 많은 기초 단계의 학습 이후에 가능할 것 같습니다. 가령, 테스트 코드 드 짜는 법은 익혔지만 이 수준에서 테스트를 진행하기도 민망해서 써먹지도 못합니다.  아쉽지만 빨리 실력 보충해서 다양한 부가 기능들 활용해가며 본격적인 프로젝트 빨리 하고 싶습니다는 생각이 듭니다.

 

실수 발견: 내 차례가 끝나면 클릭이 안 되게 막아야 하는데 그러지 못해 클릭이 계속 됩니다.

gameBoard.addEventListener('click', event => userClickHandler(event), {once:true});

: 오류 수정: addEventListener에 'once'option을 줘서 트리거 되게 하였습니다. 본인 차례일 때 매번 이벤트 리스너를 등록하게 됩니다.

: 이벤트 리스너를 등록하는 데에 얼마만큼의 자원이 소모되는 지 모르겠습니다. 더 좋은 풀이가 당장은 생각나지 않아 프로젝트 마친 뒤 해당 부분 더 고민해보겠습니다.

 

참고 예제

https://www.codebrainer.com/blog/tic-tac-toe-javascript-game

 

Simple Tic-Tac-Toe JavaScript game for beginners

Tic-Tac-Toe JavaScript game is a simple example of games you can program in JavaScript, CSS and HTML and host it yourself.

www.codebrainer.com


3.

실버 2, 골드 2 3시간 
: 1솔 .. 속상하다. 열심히 풀이하고 익히자.

: 주사위 굴리기 제외하면 다른 건 접근이 아예 안 되는 건 아니다. 마지막 한 끗 차이에서 답을 못 내는 것 같다. 디테일의 차이.. 같은 느낌. 경사로 문제는 테스트 케이스 몇 개 맞기도 한다. 

: 아예 희망이 없는 건 아니다. 끈기 있게 계속 풀이하면 된다. 오늘 내 풀이 오류도 고치고 다른 사람들 풀이도 2개씩 보기로 하자.

 

https://www.acmicpc.net/problem/14501

 

14501번: 퇴사

첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.

www.acmicpc.net

https://www.acmicpc.net/problem/1189

 

1189번: 컴백홈

첫 줄에 정수 R(1 ≤ R ≤ 5), C(1 ≤ C ≤ 5), K(1 ≤ K ≤ R×C)가 공백으로 구분되어 주어진다. 두 번째부터 R+1번째 줄까지는 R×C 맵의 정보를 나타내는 '.'과 'T'로 구성된 길이가 C인 문자열이 주어진다

www.acmicpc.net

3. 깊이 우선 탐색(DFS)과 너비 우선 탐색(BFS) 활용한 문제 유형/응용

DFS, BFS은 특징에 따라 사용에 더 적합한 문제 유형들이 있습니다.

1) 그래프의 모든 정점을 방문하는 것이 주요한 문제

단순히 모든 정점을 방문하는 것이 중요한 문제의 경우 DFS, BFS 두 가지 방법 중 어느 것을 사용하셔도 상관없습니다.

둘 중 편한 것을 사용하시면 됩니다.

2) 경로의 특징을 저장해둬야 하는 문제

예를 들면 각 정점에 숫자가 적혀있고 a부터 b까지 가는 경로를 구하는데 경로에 같은 숫자가 있으면 안 된다는 문제 등, 각각의 경로마다 특징을 저장해둬야 할 때는 DFS를 사용합니다. (BFS는 경로의 특징을 가지지 못합니다)

 

3) 최단거리 구해야 하는 문제

미로 찾기 등 최단거리를 구해야 할 경우, BFS가 유리합니다.

왜냐하면 깊이 우선 탐색으로 경로를 검색할 경우 처음으로 발견되는 해답이 최단거리가 아닐 수 있지만, 
너비 우선 탐색으로 현재 노드에서 가까운 곳부터 찾기 때문에경로를 탐색 시 먼저 찾아지는 해답이 곧 최단거리기 때문입니다.

 

이밖에도 

- 검색 대상 그래프가 정말 크다면 DFS를 고려
- 검색대상의 규모가 크지 않고, 검색 시작 지점으로부터 원하는 대상이 별로 멀지 않다면 BFS

출처: https://devuna.tistory.com/32 [튜나 개발일기:티스토리]

https://transferhwang.tistory.com/649

 

[백준/BOJ] 1189번 컴백홈

https://www.acmicpc.net/problem/1189 1189번: 컴백홈 첫 줄에 정수 R(1 ≤ R ≤ 5), C(1 ≤ C ≤ 5), K(1 ≤ K ≤ R×C)가 공백으로 구분되어 주어진다. 두 번째부터 R+1번째 줄까지는 R×C 맵의 정보를 나타내..

transferhwang.tistory.com

이 사람 240문제 풀고 아슬아슬하게 코테 붙는다고 속상해하는데 나는 꼴랑 50-70문제 ㅔ풀고 안 풀린다고 좌절하고 있었네.. 그냥 아직 도달 못 해서 그런거였구나. 계속 갈고 닦자. 괜찮다. 나 멍청한 거 아니다. 희망 있다.

 

골드

https://www.acmicpc.net/problem/14499

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지

www.acmicpc.net

https://sungmin-joo.tistory.com/2

 

[백준] 14409번 주사위 굴리기 파이썬 해설

출처 : https://www.acmicpc.net/problem/14499 14499번: 주사위 굴리기 첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고..

sungmin-joo.tistory.com

 

https://www.acmicpc.net/problem/14890

 

14890번: 경사로

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.

www.acmicpc.net

https://ryu-e.tistory.com/108

 

[Python] 백준 14890 경사로

1. 문제 링크 https://www.acmicpc.net/problem/14890 14890번: 경사로 첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같..

ryu-e.tistory.com

아 진짜 이해는 다 했는데 구현이 막힌다. 왜 나만 못할까. 다른 사람 다 잘 하는 것 같은데.

https://pacific-ocean.tistory.com/368

 

[백준] 14890번(python 파이썬)

문제 링크: https://www.acmicpc.net/problem/14890 14890번: 경사로 첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은..

pacific-ocean.tistory.com

https://2hs-rti.tistory.com/31

 

[백준] 14890번 - 경사로 (파이썬)

# 경사로 import sys input = sys.stdin.readline N, L = map(int, input().split()) arr = [] for _ in range(N): arr.append(list(map(int, input().split()))) result = 0 def check(line): global result isO..

2hs-rti.tistory.com