자바 스크립트 공부

dlgnswk·2024년 4월 7일
0

getElementById

  • 태그의 id 를 통해 태그 선택
  • 존재하지 않는 id 인 경우 null 반환

getElementsByClassName

  • 태그의 class 를 통해 태그 선택
  • 존재하지 않는 class 로 접근한 경우 빈(empty) HtmlCollection 반환
  • 반환되는 HtmlCollection의 순서는 깊이와 상관없이 html 위에서부터 반환
  • 한번만 사용된 class 인 경우에도 HtmlCollection을 반환하기 때문에 [0] 대괄호 표기법으로 접근해야함
  • HtmlCollectionfor of 문 사용 가능

getElementByTagName

  • 태그의 name을 통해 태그 선택
  • 해당하는 모든 태그를 HtmlCollection으로 반환
  • * 을 사용해 모든 태그를 선택 가능
  • 자주 사용되는 메소드는 아님

유사배열 (Array-Like Object)

  • 숫자형태의 index 사용 가능
  • length 프로퍼티 사용 가능
  • 배열의 메소드 사용 불가
  • Array.isArray 의 결과값은 false

querySelector

  • css 선택자를 통해 하나의 태그 선택
  • 괄호 안에 #id 또는 .class 또는 tagName 을 통해 태그 선택
  • .class 의 경우 여러개의 유사배열이 아니라 첫번째의 태그 하나만 선택
  • 코드가 더 짧기도 하고 하나의 메소드로 idclass를 선택 할 수 있다는 점에서 더 자주 사용됨
  • 존재하지 않는 요소를 선택하는 경우 null 이 반환
  • querySelect(#list li); 의 경우 id 가 list인 태그의 첫번째 li 태그가 선택된다.

querySelectorAll

  • css 선택자를 통해 하나 이상의 태그 선택
  • NodeList 라는 유사배열을 반환

이벤트(Event)

  1. javasciprt 파일에서 작성
// 버튼 태그
const btn = document.querySelector('#myBtn');

// 버튼을 클릭했을 경우(Event Handling)
btn.onclick = function () { // 작동하는 함수(Event Handler, Event Listner)
  console.log('hello world!');
}

또는

  1. html 파일에서 작성 (잘 사용하지 않음, js, html 파일 구분해서 작성)
<button id="myBtn" onclick="console.log('hello world!');">click</button>

DOM(Document Object Model, 문서 객체 모델)

Html 문서 전체를 객체로 표현한 것

  • document 객체가 웹 문서의 최상단 객체로 진입점의 역할을 함

  • console.log 를 통해 DOM 에 접근하면 해당하는 HTML(tag)이 출력됨

  • console.dir 를 통해 DOM 에 접근하면 해당하는 프로퍼티들이 출력됨

    logdir 의 차이점

    • 출력 방식
      log : 자료형 별로 출력
      dir : 문자열로 출력

    • 결과물
      log : 파라미터로 전달받은 값 위주로 출력
      dir : 객체의 속성을 자세하기 출력

    • 전달할 수 있는 값의 개수
      log : 쉼표로 구분되어 전달받은 모든 값을 출력
      dir : 첫번째 값만 출력

    • DOM
      log : HTML 형태로 출력
      dir : 객체 형태로 출력

DOM 트리

  • DOM 트리 예시
  • document 객체가 최상위(root)
  • 각 객체는 Node 라고 표현함
  • 상위 노드는 부모 노드(parent node), 하위 노드는 자식 노드(child node),
    같은 위치의 노드는 형제 노드(sibling node)라고 함
  • node 타입은 태그를 표현하는 요소 노드(Element node),
    문자를 표현하는 텍스트 노드(Text node), 코멘트 노드(comment node) 등 12가지로 구분함
  • 일반적으로 텍스트 노드는 요소노드의 자식노드가 되고 스스로는 자식노드를 가질 수 없음
    (잎 노드, leaf node 라고 함)

요소 노드에 접근하기

HTML

<body>
  // 이전 형제 요소 노드 없음
  <div id="content"> // 현재 요소 노드
    <h2 id="title-1">Space1</h1> // 첫번째 자식 요소 노드
    <ul id="list-1">
      <li>earth</li>
      <li>mars</li>
      <li>jupiter</li>
      <li>sun</li>
    </ul>
    <h2 id="title-2">Space2</h1>
    <ul id="list-2"> // 마지막 자식 요소 노드
      <li>neptune</li>
      <li>venus</li>
      <li>uranus</li>
      <li>mercury</li>
    </ul>
  </div>
  <script src="index.js"></script> // 다음 형제 요소 노드
</body>

 

Javascript

// 현재 요소 노드
const myTag = document.querySelector("#content");

// 부모 요소 노드
myTag.parentElement // <body>...</body>

// 자식 요소 노드
myTag.children // 모든 자식 요소 노드 HtmlCollection 으로 리턴
myTag.firstElementChild // <h2 id="title01">...</h1>
myTag.lastElementChild  // <ul id="list-2">...</ul>

// 형제 요소 노드
myTag.previousElementSibling // null
myTag.lastElementSibling     // <script src="index.js"></script>

요소 노드의 주요 프로퍼티

  • innerHTML : 요소 안에 있는 HTML 자체를 문자열로 리턴 (줄바꿈, 들여쓰기 포함)
    하지만 요소 내 확인보다는 새로운 HTML 코드를 할당해 수정에 자주 사용됨
  • outerHTML : 해당 요소를 포함한 HTML 자체를 문자열로 리턴 (줄바꿈, 들여쓰기 포함)
    새로운 HTML 코드를 할당 할 경우 새로운 요소로 교체됨
    따라서, 재할당해야하는 경우가 생김
  • textContent : 요소 내의 HTML을 제외한 텍스트만 리턴
    새로운 텍스트를 할당하여 요소 내 값 수정가능(특수문자도 텍스트로 반영)

모든 노드에 접근하기

텍스트 노드를 포함한 다른 노드로 이동하고 싶은 경우

  • node.childeNodes : nodeNodelist
  • node.firstChild : node 의 첫번째 자식 노드 하나
  • node.lastChild : node 의 마지막 자식 노드 하나
  • node.parentNode : node 의 부모 요소 하나
  • node.previousSibling : node 의 이전, 좌측의 노드 하나
  • node.nextSibling : node 의 이후, 우측의 노드 하나

요소 노드 추가하기

  • 요소 노드 만들기
    createElement('태그이름')
     
  • 요소 꾸미기
    textContent 또는 innerHtml
     
  • 요소 넣어주기
    prepend : 요소의 첫번째 자식 노드로 추가
    append : 요소의 마지막 자식 노드로 추가
    before : 요소의 이전 형제 노드로 추가
    (여러개의 값을 전달할 경우, 전달한 순서대로 노드를 한번에 추가 가능)
    after : 요소의 다음 형제 노드로 추가

노드 삭제하기

  • remove : 노드 삭제하는 메소드
const solar = document.querySelector('#solar');

solar.children[2].remove(); // solar 노드의 3번째 자식 요소 노드를 삭제
solar.remover(); // solar 요소 노드를 삭제

노드 이동하기

  • prepend : 첫번째 자식 요소 노드로 이동
  • append : 마지막 자식 요소 노드로 이동
  • before : 이전 형제 요소 노드로 이동
  • after : 다음 형제 요소 노드로 이동

html

<h1>solar1</h1>
<ol id="solar1">
  <li>태양</li>
  <li>수성</li>
  <li>금성</li>
</ol>
<h1>solar2</h1>
<ol id="solar2">
  <li>지구</li>
  <li>화성</li>
  <li>목성</li>
</ol>

 

javascript

const solar1 = document.querySelector('#solar1');
const solar2 = document.querySelector('#solar2');

solar1.append(solar2.children[2]); // 목성을 solar1 노드의 마지막 자식노드로 이동
solar2.children[0].after(solar1.children[0]); // solar2 첫번재 자식노드 뒤에 태양을 이동

HTML 속성 다루기

  • elem.id : 요소 노드의 id 리턴
  • elem.className : 요소 노드의 class 리턴
     
  • elem.getAttribute('속성') : 표준, 비표준 관계없이 속성에 접근 가능(대소문자 구분 x)
  • elem.setAttribute('속성', '값') : 속성 추가 및 수정 가능(대소문자 구분 x)
  • elem.removeAttribute('속성') : 속성 삭제(대소문자 구분 x)

스타일 다루기

  • elem.style.cssType = 'css' : 카멜 표기법 사용
    태그에 직접적으로 적용이 되어 스타일 우선순위가 높아짐, 중복 증가
    따라서, tagclass 를 변경하는 것이 더 권장됨
     
  • elem.className = 'className' : className 을 변경하여 미리 작성해둔 css를 적용
    클래스 속성값 전체가 변경됨(추가x)
     
  • elem.classList : class의 속성값을 유사배열로 다루는 프로퍼티
  • elem.classList.add('className') : 해당 이름의 class 속성을 추가
    쉼표를 사용하여 여러개의 class 추가 가능
  • elem.classList.remove('className') : 해당 이름의 class 속성을 제거
    쉼표를 사용하여 여러개의 class 제거 가능
  • elem.classList.toggle('className') : 해당 이름의 class가 존재하는 경우 삭제, 존재 하지 않는 경우 추가
    쉼표를 사용하여 여러개의 class 토글 불가
    • elem.classList.toggle('className', true) : add 의 기능만 강제함
    • elem.classList.toggle('className', false) : remove 의 기능만 강제함

dataset

비표준 속성을 사용해서 코드를 작성할경우 생기는 문제를 대비해서
data-* 속성을 사용하는 것을 권장

이 경우 elem.dataset.* 의 프로퍼티로 접근해서 값을 가져올 수 있음

if()문을 사용하여 판별 가능

if(e.target.dataset.title) {}; // target의 data-title이 있다면 true 리턴함

만약 data-title 이라는 비표준 속성이 없다면 undefined 리턴
(javascript에서는 0, -0, null, undefined, "", false, NaNfalsy 값)


이벤트 핸들러 등록

  • elem.onclick : 새로운 이벤트 핸들러 등록시 덮어쓸 수 있고 여러개의 핸들러 다룰수 없음

  • elem.addEventListner('event', handler) : 이벤트 핸들러를 등록할 때 가장 권장되는 방식
    하나의 메소드에 여러개의 이벤트 핸들러를 등록할 수 있음

  • elem.removeEventHandler('event', handler) : 등록한 이벤트 핸들러를 제거 할 수 있음
    이벤트 핸들러를 삭제해야 할 경우가 있는경우 handler 에 외부로 된 함수를 사용해야 함
    handler 에는 괄호를 뺀 함수 이름만 기입하면 됨
    괄호를 기입 할 경우 함수를 실행하고 나오는 리턴값이 두번째 파라미터로 입력됨

// 이벤트 핸들러 등록
button.addEventListner('click', function() { console.log('hi!'); });
// 이벤트 핸들러 삭제 불가 (다른 이벤트 핸들러로 인식함)
button.removeEventListner('click', function() { console.log('hi!'); });

// 따라서 외부함수로 작성된 핸들러를 사용해야 함
function hi() { console.log('hi!') };
// 이벤트 핸들러 등록
button.addEventListner('click', hi);
// 이벤트 핸들러 삭제 가능
button.removeEventListner('click', hi);

이벤트의 종류

마우스 이벤트

  • mousedown : 버튼을 누르는 순간

  • mouseup : 버튼을 눌렀다 떼는 순간

  • click : 왼쪽 버튼을 클릭한 순간

  • dbclick : 왼쪽 버튼을 더블 클릭한 순간

  • contextmenu : 오른쪽 버튼을 더블 클릭한 순간

  • mousemove : 포인터가 움직인 순간

  • mouseover : 포인터가 요소 위로 올라온 순간

  • mouseout : 포인터가 요소에서 벗어나는 순간

  • mouseenter : 포인터가 요소 위로 올라온 순간(버블링 없음)

  • mouseleave : 포인터가 요소에서 벗어나는 순간(버블링 없음)

    0. 마우스 버튼 프로퍼티

    mouse.button : 0: 마우스 왼쪽 버튼, 1: 마우스 휠, 2: 마우스 오른쪽 버튼

    1. 마우스 왼쪽 버튼 이벤트

    클릭한 경우 mousedown -> mouseUp -> click 순서대로 이벤트 발생

    더블 클릭한 경우
    mousedown -> mouseUp -> click -> mousedown -> mouseUp -> click -> dbclick 순서대로 이벤트 발생

    2. 마우슨 오른쪽 버튼 이벤트

    윈도우 운영체제의 경우
    mousedown -> mouseup -> contextmenu

    운영체제의 경우
    mousedown -> contextmenu -> mouseup
    (mouseup 의 경우 contextmenu의 메뉴창이 뜨면 실행되지 않음)

    마우스 이동 프로퍼티

    mouse.target : 이벤트 발생한 요소
    mouse.relatedTarget : 이벤트가 발생하기 직전(mouseover) 혹은 직후(mouseout)에 마우스가 위치해 있던 요소

    mouseenter , mouseleave VS mouseover , mouseout

    mouseenter , mouserleave :
    버블링과 이벤트 위임이 일어나지 않음
    자식요소의 영역을 계산, 구분하지 않음

    이벤트가 자식요소에 영향을 끼치는지 유무가 가장 큰 차이

키보드 이벤트

  • keydown : 키보드 버튼 누르는 순간

  • keypress : 키보드 버늩 누르는 순간(알파벳, 숫자 등 출력이 가능한 키에서만 동작, shift, esc 등의 키에는 반응하지 않음)

  • keyup : 키보드 버튼을 눌렀다 떼는 순간

    0. 키보드 프로퍼티

    keyBoard.key : 이벤트가 발생한 버튼의 값
    keyBoard.code : 이벤트가 발생한 버튼의 물리적인 키보드 위치 값

    keyBoard.type : keydown keypress keyup

    • keydown : 키보드를 누를 때 발생
      (계속누르고 있는 경우 keypress -> keydown-> keydown -> keydown -> ... -> keyup)
    • keypress : 키보드를 누를 때 발생(shift, esc 등 출력값이 없는 경우,
      영어가 아닌 경우 발생 안함, 웹표준에서 권장하지 않음)
    • keyup : 키보드를 뗄 때 발생

포커스 이벤트

  • focusin : 요소에 포커스가 되는 순간
  • focusout : 요소로부터 포커스가 빠져나간 순간
  • focus : 요소에 포커스가 되는 순간 (버블링x)
  • blur : 요소로부터 포커스가 빠져나가는 순간 (버블링x)

입력 이벤트

  • change : 입력된 값이 바뀌는 순간
  • input : 값이 입력되는 순간
  • select : 입력 양식의 하나가 선택되는 순간
  • submit : 폼을 전송하는 순간

스크롤 이벤트

  • scroll : 스크롤 바가 움직일 때

윈도우 창 이벤트

  • resize : 윈도우 사이즈를 움직일 때

이벤트 객체

function click(event) { //event 또는 e 로 사용할 수 있음
  console.log(event); // event에 관한 프로퍼티들을 볼 수 있음
  event.target.style.color = 'red'; // event.target 은 해당 이벤트가 일어난 요소에 접근
}

이벤트 객체 프로퍼티

공통 프로퍼티

  • type : 이벤트 이름 (click, mouseup, keydown 등)
  • target : 이벤트가 발생한 요소
  • currentTarget : 이벤트 핸들러가 등록된 요소
  • timeStamp : 이벤트 발생 시각 (페이지가 로드된 이후부터 경과한 밀리초)
  • bubbles : 버블링 단계인지를 판단하는 값

마우스 이벤트 관련 프로퍼티

  • button : 누른 마우스의 버튼 (0: 왼쪽, 1: 가운데(휠), 2: 오른쪽)
  • clientX, clientY : 커서의 브라우저가 표시하는 화면 내 영역에서의 위치
    스크롤 위치와 무관하게 항상 보여지는 화면의 좌측 상단 모서리 위치를 (0, 0)으로 계산
  • pageX, pageY : 커서의 전체 문서 영역에서의 위치
    스크롤로 인해 보이지 않는 화면의 영역까지 측정
  • offsetX, offsetY : 커서의 이벤트 발생한 요소 (target) 에서의 위치
    항상 target의 상단 모서리 위치를 (0, 0) 으로 계산
  • screenX, screenY : 커서의 모니터 화면 영역에서의 위치
  • altKey : 이벤트가 발생할 때 alt 를 눌렀는지
  • ctrlKey : 이벤트가 발생할 때 ctrl 를 눌렀는지
  • shiftKey : 이벤트가 발생할 때 shift 를 눌렀는지
  • metaKey : 이벤트가 발생할 때 meta 키를 눌렀는지(window, cmd)

;

키보드 이벤트 관련 프로퍼티

  • key : 누른 키가 가지고 있는 값
  • code : 누른 키의 물리적인 위치
  • altKey : 이벤트가 발생할 때 alt 눌렀는지
  • ctrlKey : 이벤트가 발생할 때 ctrl 를 눌렀는지
  • shiftKey : 이벤트가 발생할 때 shift 를 눌렀는지
  • metaKey : 이벤트가 발생할 때 meta 키를 눌렀는지(window, cmd)

DOM 이벤트 발생 순서

1. 캡쳐링 단계 (Capturing Phase)

이벤트가 발생하면 가장 먼저, 버블링의 반대방향으로 진행되는 이벤트 전파 방식

보통은 타겟에 도달해서 이벤트 핸들러를 동작시키고 버블링 단계에서
각 부모 요소의 이벤트 핸들러가 동작됨

캡쳐링 단계에서 이벤트 핸들러를 동작 시키려면
addEentListener 의 세번째 프로퍼티에 true 또는 capture:true 를 전달

2. 타겟 단계 (Target Phase)

가장 처음 이벤트 핸들러가 동작하게 되는 순간

3. 버블링(Bubbling Phase)

하나의 요소에 이벤트가 발생하게 되면 해당 요소의 핸들러가 동작하고
같은 타입의 이벤트에 한해서 부모의 이벤트 핸들러도 동작하게 되는 현상
가장 최상단의 window 객체를 만날 때까지 이 과정을 반복

이때, event.target 프로퍼티는 이벤트가 일어나는 모든 요소들을 담지 않고
처음 발생한 요소를 담고 있음
이벤트가 일어나는 모든 요소를 확인하고 싶다면 event.currentTarget 프로퍼티 사용

이벤트를 멈추고 싶다면 event.stopPropagation 프로퍼티 사용
하지만 이벤트 버블링을 막는것은 필요한 경우가 아니면 가급적 하지 않는것이 좋음
상위 요소에서 이벤트를 등록했을 때 버블링을 막은 해당 요소에 원하는 이벤트를 적용시킬 수 없음


이벤트 위임 (Event Delegation)

어떤 요소의 자식 요소를 이벤트 핸들러로 등록했을 때 새로운 자식요소가 추가 될 경우
새로 추가된 요소는 핸들러로 등록되지 않는 문제가 발생함

이를 위해 버블링을 활용하여 자식요소에 작동할 이벤트 핸들러를 부모 요소에 작성하면 자식요소는 부모 요소의 이벤트 핸들러를 위임받아 사용할 수 있음

하지만 이렇게 작성할 경우 부모 요소에 이벤트가 발생 할 수 있기 때문에

if(e.target.classList.contains('자식요소클래스')){ 이벤트 };
// 또는
if(e.target.tagName === '자식요소태그'){ 이벤트 };

이런식으로 구분할 필요가 있고 이런 방식은 코드의 길이를 줄이고 성능을 향상시키는데 도움을 줌


이벤트 방지

event.preventDefault : 이벤트 객체의 preventDefault 메소드는 아래 코드처럼 특정 이벤트를 방지할 수 있음

// text에서 클릭 이벤트를 막음
text.addEventListner('click', function(event) {
  event.preventDefault();
  alert("Don't click!");
});

// 문서 전체에서 오른쪽 클릭 이벤트를 막음
document.addEventListener('contextMenu', function(e) {
  e.preventDefault();
  alert("마우스 오른쪽 클릭은 사용할 수 없습니다");
});

하지만 이벤트 방지할 때 각 태그의 고유기능을 훼손할 수 있으므로 꼭 필요한 경우에만 사용함


input

  • focusin : 요소에 포커스가 되었을 때
  • focusout : 요소에 포커스가 빠져나갈 때
  • focus : 요소에 포커스가 되었을 때 (버블링 x)
  • blur : 요소에 포커스가 빠져나갈 때 (버블링 x)
     
  • input : 사용자가 입력을 할 때
  • change : 요소의 값이 변했을 때 (focusout 직전에 입력값이 변경되었을 경우 발생)

scroll

스크롤은 일반적으로 window 객체의 프로퍼티를 사용함

  • window.scrollX : 문서 왼쪽을 기준으로 0px
  • window.scrollY : 문서 위쪽을 기준으로 0px
profile
The loop will end some day

0개의 댓글