Coding/Today I Learned (148)

07
06

1. onsubmit

  • 입력받은 정보들을 전송한다.
  • 회원가입과 같은 기능에서 입력된 정보들을 전송할 수 있다.

2. onchange

  • 데이터 변화를 감지한다.

3.  onmouse 이벤트

  1. onmouseenter : 마우스 포인터가 요소안으로 들어왔을 때 발생하는 이벤트이다. ( CSS의  hover 같은 상황 ) 자식 요소도 모두 포함한다. 마우스가 요소 밖으로 나갔다가 다시 들어오지 않는 이상 이벤트는 발동하지 않는다.
  2. onmouseover : onmouseenter의 반대의 경우. 영역을 벗어나지 않아도 가능.
  3. onmouseout : 위와 반대로,  마우스 포인터가 밖으로 나왔을때 혹은, 자식 요소에 들어가면 발생하는 이벤트.
  4.  onmousemove : 마우스 포인터가 요소 안에서 움직일때 발생하는 이벤트.

4. onkey 이벤트

  1. onkeyup : 키보드가 올라 올때 발생하는 이벤트
  2. onkeydown : 키보드가 눌려졌을때 발생하는 이벤트
  3. onkeypress : 키보드가 눌려졌을때 발생하는 이벤트.
    • onkeydown과 달리 키보드가 계속 눌려진 상태에서도 이벤트가 계속 발생하는점이 다르다.

5. event.stopPropagation

  • 이벤트 실행시 부모요소의 이밴트 전달을 중지하라는 의미.
  • 이벤트는 실행될 시 부모 요소까지 이벤트를 전달한다. 이를 멈춰서 자신이 속한 요소의 이벤트만 실행시킨다.

6.  event.preventDefault

  • 페이지를 이동하거나, 혹은 전송 ( 아까 onsubmit ) 등을 사용하였을 때, 페이지가 리로드 되는 것을 막아준다.
  • 페이지 리로드를 막기 위하여, event.stopPropagation을 사용한다면, URL이동 자체도 되지 않을 것이다.
  • 그래서 지금의 이벤트로 만들어진 상태를 '유지한다'는 의미를 가지고 있는 preventDefault를 사용한다.
COMMENT
 
07
05

1. DOM?

  • HTML은 그저 구조를 흩뿌려 놓은 데이터이다.
  • 그러므로, 컴퓨터는 데이터를 렌더링 할 뿐이지 어떤 데이터가 들어 있는지는 알 수 없다.
  • 이것을 자바스크립트로 옮겨 컴퓨터가 데이터를 알게 해 주는 것이 Document Object Model, DOM이다.

2. 각 엘리먼트에 접근하기

  •  HTML도 자바스크립트와 같이 '트리구조'로 이루어져 있다.
  • 그래서 서로의 부모와 자식 요소에 접근이 가능하다.
  • document.children [원하는 요소의 index]를 사용해서 자식 요소에 접근한다.
  • document.children [원하는 요소의 index]. parentNode부모 요소에 접근한다.
  • 변수로 각 요소의 주소를 할당할 수 있다. document 어쩌고 하면서 적는 것보다 빠르고 간단하다.
    • Ex) (콘솔 창에서) head = document.children [0]. children [0] =>  head만 입력해도 됨.
  • 위의 예시를 이용해 다른 방법으로 요소에 접근할 수 있는 방법들을 더 알아보겠다.
    • head.firstElementChild => head의 첫 번째 자식 요소
    • head.lastElementChild => head의 마지막 자식 요소
    • head.nextElementSibling => head의 다음에 올 형재 요소
    • head.previousElementSibling => head의 이전에 올 형재 요소 ( 정상적 파일에서는 head 이전의 형재 요소는 없다. 뜻만 이해 하자. )

3. 요소 추가와 삭제

  • 요소에 접근하여 수정하는 것은 물론 가능하고, 새로운 요소를 추가할 수도 있다.
  • document.createElement('추가할 요소의 element 이름')
    • Ex) document.createElement('div') => 기존의 요소와 아무 상관(형재나 부모 자식 같은 관계가 없는) div요소를 하나 만든다.
  • 위에서 만들어진 element를 기존의 element들과의 관계를 설정한다.
    • Ex) testDiv = document.createElement('div') => element를 새롭게 만들면서 변수에 할당해 놓는다. 
      document.body.append(testDiv) => body안에 만든 testDiv를 자식으로 넣어준다.
    • append를 appendChild로 바꿔도 똑같이 자식 요소로 넣어준다.
      • appendChild는 오직 Node객체만 받을 수 있고, 다중 문자를 넣을 수 없고, 리턴값이 있다는 점이 다르기는 하나 위의 예시에서는 같은 기능을 하고 있다.

4. 샐렉터를 선택해서 값을 변경하기

  • 요소를 만들고 관계를 설정까지 할 수 있다면, 값을 넣어서 화면에 렌더링 시킬 수 도있다.
  • 이때 우리는 querySelector과 querySelectorAll을 사용한다.
    • Ex) 파일에 class이름이 'user'인 요소가 있을 경우
      document.querySelector('. user') => class이름이 user인 가장 처음에 있는 HTML요소를 '유사 배열'로 가져온다.
    • Ex) 파일에 class이름이 'user'인 요소가 여러 개 있을 경우
      document.querySelectorAll('. user') => class이름이 user인 모든 HTML요소를 '유사 배열'로 가져온다.
  • 선택된 요소를 변수로 담아서 계속 사용하는 것이 유리하다. ( 중요하다고 생각되어 한번 더 넣는다! )
    • Ex) firstUser = document.querySelector('. user')
      이후 div로 userInfo를 첫 번째 user에 만들어 넣고 싶을 경우
      => userInfo = document.createElement('div')
      => firstUser.append(userInfo)
  • 선택된 요소에 textContent를 이용해 문자를 값으로 넣을 수 있다.
    Ex) userInfo.textContent = 'Name: Hendrix'
  • 선택된 요소에 class를 추가할 수 있다.
    Ex) userInfo.classList.add('name')
    • class를 넣어 줌으로써, 앞의 요소들과 묶어 주어 원래 있던 CSS를 적용시킨다거나 하는 일들을 할 수 있다.
  • 선택된 요소를 remove를 이용해 삭제할 수도 있다.
     Ex) userInfo.remove() => 이는 정확히 내가 지울 userInfo가 어디 있는지 알고 있을 때만 사용할 수 있다.
    • 여러 개의 자식 엘리먼트를 다 지우려고 할 경우
      Ex) document.querySelector('. user'). innerHTML = '';
    • 하지만 위의 방법의 경우 전달 내용이 빈 string인 원시 데이터 형태로 들어가기 때문에 보안 위험이 있다.
    • 그래서 반복문과 같은 원래 HTML에 포함된 메서드를 이용하는 것이 옳다.
      Ex) while(body.firstChild) {body.removeChild(body.firstChild);} => body의 첫 번째 자식 요소가 있다면, 그것을 제거한다.
      • 혹은, 반복문의 조건을 body.children.length > 1과 같이 조절하여 요소가 몇 개 남을 때까지(지금은 1개가 남을 때까지) 삭제를 할 수도 있다.
      • 혹은, 배열로 요소를 가져오는 것을 생각해 본다면, 고차 함수를 이용하거나, for... of 구문을 이용하여 삭제하길 원하는 클래스 이름을 가진 모든 요소를 삭제할 수 도 있다.
COMMENT
 
07
04

1. printKeyValue

  • 객체를 입력받아  string 타입으로 key: value의 형식으로 리턴한다.
  • 각 키와 값의 사이에 줄바꿈으로 다른 요소라는 것을 표시한다.
function printKeyValue(obj) {
  let result = ''; // string 타입으로 리턴해야 하기 때문에 빈 스트링을 만든다.
  for(let key in obj) { // for...in 으로 객체를 돌면서 key 값을 구한다.
    result = result + `${[key]}: ${obj[key]}\n` // 벡틱을 이용해 한줄에 알맞은 요소를 넣고 result에 쌓는다.
  }
  return result; // 완성된 result를 리턴한다.
}
  • 줄 바꿈은 '\n' 이다.
  • 만약, Object.keys(obj)를 사용한다면, 모든 키를 받아 버리기 때문에 키 하나하나씩을 선택할 수 없게 된다.

2. arrayInSameKey

  • 배열과 객체를 받아, 배열의 요소가 객체의 키와 같을경우 새로운 객체 안에 넣어서 리턴한다.
  • 같지 않은 요소는 무시한다.
function arrayInSameKey(arr, obj) {
  let result = {}; // 빈 객체를 만든다.
  for(let key in obj) { // 반복문으로 객체안의 Key를 추출한다.
    for(let i = 0; i < arr.length; i++) { // arr를 하나씩 확인하면서,
      if(key === arr[i]) { // 키와 같은 데이터가 있는지 검색한다.
        result[key] = obj[key] // 같은 데이터를 result안에 같은 키와 값은 obj[key]에서 가져와 할당한다.
      }
    }
  }
  return result; // 완성된 객체를 리턴한다.
}
  • 이중반복문이 복잡하다고 생각하고, 쓰지 않고 어떻게든 풀어보려고 했지만 이것이 가장 간단한 방법으로 보인다.
  • 리펙토링도 좋지만, 일단 알고 있는 답을 애써 무시하고 처음부터 다른 방법으로 찾으려 하는 것 보다, 일단, 알고 있는 방식으로 답을 작성 해 놓고 이후, 리펙토링을 통해 코드를 정리할 생각을 해야한다.
COMMENT
 
07
02

1. Spread 및 Rest를 객체에서 사용하기

  • spread는 배열을 그대로 복사하거나, 합치고 객체에서도 사용이 가능하다.
let obj1 = { foo: 'bar', x: 42 };
let obj2 = { foo: 'baz', y: 13 };

let clonedObj = { ...obj1 }; // obj1의 키와 값이 그대로 복사가 된다.
let mergedObj = { ...obj1, ...obj2 }; // obj1과 obj2의 같은 이름의 키인 'foo'가 있으므로 이후에 온 obj2의 foo로 다시 할당된다.
console.log(clonedObj) // {foo: "bar", x: 42}
console.log(mergedObj) // {foo: "baz", x: 42, y: 13} 이때,겹치지 않는 키는 그대로 추가된다.
  • 함수에서도 사용이 가능하다. 주로, 파라미터들을 가져오는 데 사용한다. slice와 같이 원하는 부분을 잘라서 가져올 수 있다.
function myFun(a, b, ...manyMoreArgs) {
  console.log("a", a); // 'a', one
  console.log("b", b); // 'b, two
  console.log("manyMoreArgs", manyMoreArgs); // 'manyMoreArgs', ["three", "four", "five", "six"]
}

myFun("one", "two", "three", "four", "five", "six");
  • Spread 나 Rest는 변동이 있을 수 있는 파라미터를 가진 함수나, 배열에 주로 사용하기 편하다. 아무리 추가, 삭제가 일어나도 그대로 배열을 가지고 올 수 있기 때문이다. 그 이후  sort와 같은 메서드를 이용하기도 매우 유용하다. 변화가 있더라도 변화된 그대로 다음 메서드를 실행시켜 줄 수 있다.

2. 구조 분해 할당

  • 구조 분해 할당은 Spread를 사용한 후, 값을 해체한 뒤에 다시 변수로 할당해 준다.
function f(...[a, b, c]) {
  return a + b + c;
}

f(1)          // NaN (b 와 c 는 undefined)
f(1, 2, 3)    // 6
f(1, 2, 3, 4) // 6 (4번 째 파라미터는 해체되지 않음)
  • 마찬가지로 객체에서도 사용이 가능하다.
const {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
console.log(a) // 10
console.log(b) // 20
console.log(rest) // {c: 30, d: 40} // 위의 a, b는 값을 리턴하지만, spread로 다시 할당하면 모든 키와 값을 다 가져온다.
  • 객체에서의 구조 분해 할당은 꼭 선언과 함께 해야 한다. 아닐 경우 다른 문법으로 잘 못 읽을 수 있다.
  • 함수에서의 객체 분해를 이용할 수 있다.
function whois({displayName: displayName, fullName: {firstName: name}}){
  console.log(displayName + " is " + name);
}

let user = {
  id: 42,
  displayName: "jdoe", // 위의 whois 함수에서 displayName의 값이 그대로이기 때문에 jdoe을 리턴.
  fullName: {
      firstName: "John", // fullName의 값이 구조 분해 할당으로 firstName을 name을 선언하여 할당하고 있다.
      lastName: "Doe"
  }
};

whois(user) // 결국, displayName은 그대로 "jdoe", name은 firstName이 할당 되어 있으니, "John"
// jdoe is John

 

COMMENT