I. 들어가며
1. 전날 의문들 질문
1) 이터레이터에 next() 는 무엇?
이터레이터는 index를 포함하는 서비스를 의미하는거야
모든컬렉션에 next()로 데이터를 꺼내고 싶었어, 모든 컬렉션이 next() 있지는 않아
이터레이터 함수를 호출해서 얻어낸 객체를 통할 때 next()
이터레이터란 인덱스를 가지고있는 녀석이야!
왜 인덱스 가진 녀석을 별도로 따로 만들었을까? 인덱스 쓰는 경우 문제가 있어 멀티 스레드인 경우에 문제가 돼!
스레드가 하나 더 늘어날때 마다 이빨이 빠지게 돼 결국 해결하기위해서 개별적으로 인덱스를 두는거야!
인덱스의 한세트인 각각의 이터레이터 를 만들어서 이빨을 안빠지게 하는거야
함수가 이터레이터 같은 서비스를 가지고 있다고해도, 저 녀석은 for-of문에서 사용할 수 없다는 것을 보여주려고 쓴거야
-
js 는 타입을 정할 수없기 때문에 설계도라는 약속을 symbol()을 사용하는거야
어떤언어든 이터레이터 얻어서 사용하는데, 왜냐 반복할때 사용하는 서비스함수라고 생각하자
2) 프로미스관련 (필요성, 이유를 공감하자)
프로미스가 힘든건 낯선건데, 필요성을 공감해야한다
그전에 좋은코드란 무엇일까? 가로로 긴코드, 세로로 긴 코드가 있어
좌측이 바람직한코드야 우측 한줄이 길다는건 복잡하게 한줄로 있다는거야
좌측은 풀어져서 가독성이 좋아
함수 중첩은 가능한없는게 좋은거야 구멍이 생길 수있어
실제로 콜백함수는 {} 의 중복인 중첩이 연속되는건데, 이것을 promise()를 이용하면 하고나서, 내리고 하는 방식으로 해서 {} 중복이 덜어낼 수있다.
최근 라이브러리는 점점 promise방법을 이용하고 있어
결국 XHR보다 fetch API가 더 좋을 수있어
II. DOM
1. 들어가며
(1) dom 의의
1) dom의 필요성
숨겨져 있는 모달창 화면에 띄울 때 클래스 속성하나당 보이고 안보이고 할 수있는데, 속성 하나를 변수화 해야해
이런것은 데이터 바인딩으로 얘를 보이는 등으로 가능하다
숨겨있는게 아니라 버튼 클릭했을 때 모달을 만들고 싶을 때(미리 숨기면 메모리 먹음)는 만드는 작업할 때 변수로 바인딩된 녀석으로 만들 수없고, DOM만들고, DOM띄을 수 있어야해, dom은 뷰든 리액트든 분명히 가져야하고, 애를 통해서 할 수없는것을 확장할 수 있게 되는거야
기본적인 세팅은 데이터 바인딩으로 끝내고, 특화된것은 dom으로 할 수있어야하는거야
2. dom 실습
(1) html 해보기
1) 태그 동적으로 생성하기
노드 생성하고 선택하고 조작 할 수 있어야 해
노드를 직접 만들수도 있지만, 내가 안만들 수 있어 노드는 내가 만드는게 가능한데,
왼쪽은 html로 우측은 js 로 hello 출력한거야
(2) node의 의미와 노드 생성
1) node의 의미 : 줄기
node란 문서를 구성하는 모든객체이다
node의 뜻은 나무의 마디일까? 문서를 나무에 비유하고 있고, 각 문서의 컨텐츠는 나무의 가지처럼 이용이가능해
각 문서의 컨텐츠는 나무의 가지이고, 그 가지를 이어주는 것이 노드야
분기점 마다 마디로 비유하고있어
section 가지에 계속해서 마디마다 h1 ul li 등의 가지를 치고 있어
즉 section 마디 에서 h1, ul 줄기가 뻣어나가! 문서에 달린 모든것이 node이다.
class 부터 등등은 모두 가지가 따로 뻣어나가
2) 노드생성
// 0. 노드생성
{
let node = document.createTextNode("hello");
document.body.append(node);
}
노드를 만들어 document.body에다가 추가한다.
(3) node 선택
1) 노드 선택
노드 은 html로 엘레먼트를 이용할거야 (엘레먼트는 노드의 종류 중 하나) 노드를 선택해서 하는 방법으로 주로 해보자
let txtNode = document.getelementById() => 단일
(복수는 class, tag)
<body>
<!-- 호호 -->
<section id="s1">
<h1 class="aaa">문서</h1>
<ul>
<li>a</li>
<li>b</li>
</ul>
</section>
hello
</body>
//1. 노드 선택
{
let s1 = document.getElementById("s1");
let els = document.getElementsByTagName("section");
console.log(s1);
console.log(els[0]);
console.log(els[1]);
}
id 는 단일 하나/ section 태그는 당장은 하나여서 els[1]번 배열은 아무 것도없다.
section 채로 받으면 배열로 log가 가능해
하위자식을 검색할 때는 매개해서 큰 태그를 먼저 선택한 뒤에 한다.
2) node type들
우리가 여기서 관심을 가지는것은 document(9) Element(1) Text(3) 노드 3가지야 (9,1,3번)
실제로 이런 번호로 지정이 다 되어있어
node는 type을 알 수있어 + node조작(추가,수정,삭제) 기능 + node생성(document)
node 추가는 appand,child() 가 있어 / 삭제는 remove()
다큐먼트 기능, 엘레먼트 기능 각기 달라 어떤 역할을 하는지 기억을 해두자!
3) 엘리먼트 선택
// 울타리 찾을 때 (단독들)
let s1 = document.getElementById("s1");
let els = document.getElementsByTagName("section");
let s2= document.body.getElementsByClassName("section1");
//울타리 안쪽 찾을 때 (복수들)
// document.getElementsByClassName
// document.getElementsByTagName
s2.getElementsByClassName("aaa");
console.log(s2[0]);
console.log(s1);
console.log(els[0]);
console.log(els[1]);
울타리 사이를 생각하면서 선택하자
4)
// Slectiors API -> 선택자 이용하는것 -> 가져오면 뭐해 활용해야지!! 조작!
let s3 = document.querySelector("#s1");
let li = document.querySelectorAll("li");
CSS셀렉터를 이용한 방법도 있다.
(4) 노드 조작
1) 삭제
let s3 = document.querySelector("#s1");
let first = s3.querySelector("li:first-child");
console.log(first);
//1 삭제
first.parentNode.remove(first); //Node인터페이스에 있는기능
first.remove(); // Element 인터페이스에 있는 기능
console.log(first);
노드삭제의 경우 다음과 같이 node인터페이스의 기능이나, Element인터페이스의 기능 두개중 하나를 이용해서 한다
다만 이 경우에 나는 삭제가 되지않았다
그 이유는 쿼리셀렉터all 이 있었기 때문이다.
2)추가
//붙이는건 도큐먼트로
let li = this.document.createElement("li"); //태그 만들기
let txt = this.document.createTextNode("c"); //텍스트 만들기
let ul = s3.querySelector("ul");
ul.appendChild(li);
li.appendChild(txt);
ul태그에다가 먼저 li태그를 붙여준다
붙여진 li태그에다가 txt(컨텐트) 를 붙여준다.
3) 변경
//3 변경
{
//사실 그렇게 바람직한 방법은 아님
//첫번째것 한번에 얻어오는 방법
// let li = s3.querySelector("ul>li:first-child");
// let last = s3.querySelector("ul>li:last-child");
//ul 얻은 다음에 얻은 것 가지고 하는것이 바람직함
let ul = s3.querySelector("ul");
let li = ul.querySelector("li:first-child");
let last = ul.querySelector("li:last-child");
// li -> last 위치로 옮기는 코드
// ul.replaceChild(여기에, 새로운놈);
// ul.replaceChild(li, last);
ul.replaceChild(last, li); //새로운놈, 여기에
}
replaceChild()를 하면 새로운놈을 목적지로 넣기가 가능하다.
c를 첫번째 a로 옮겨준다
{
//사실 그렇게 바람직한 방법은 아님
//첫번째것 한번에 얻어오는 방법
// let li = s3.querySelector("ul>li:first-child");
// let last = s3.querySelector("ul>li:last-child");
//ul 얻은 다음에 얻은 것 가지고 하는것이 바람직함
let ul = s3.querySelector("ul");
let li = ul.querySelector("li:first-child");
let newOne = ul.querySelector("li:last-child");
// li -> last 위치로 옮기는 코드
// ul.replaceChild(여기에, 새로운놈);
// ul.replaceChild(li, last);
let oldone = ul.replaceChild(newOne, li);
ul.appendChild(oldone);
}
없어졌던 a를 다시 붙일 수 있게 되었다
(5) 노드조작 예제
1) 버튼을 누르면 노드가 움직이게끔 하자
//3. 노드조작을 위한 예제1
{
let btnUp = this.document.querySelector(".btn-up");
let btnDown = this.document.querySelector(".bnt-down");
let ul = this.document.querySelector("ul");
let current = ul.querySelector("li:first-child");
btnUp.onclick = function(){
//currnet 항목을 위로 올리는 것
}
btnDown.onclick = function(){
//current 항목을 밑으로 내리는것
current.
}
}
노드순회시
그런데 다음 자식을 어떻게 얻을까? nextsibling이다. 그런데 이거는 node 인터페이스 때문에 안쓰는거야!
엘레먼트 기준으로만 해야해 => current.nextElementSibling //을 쓰면돼
current.nextSibling //모든 노드를 대상으로 함
current.nextElementSibling; //다음
current.parentElement; //부모
current.previousElementSibling;
current.firstElementChild;
current.lastElementChild;
|
2) 모코드의 시도
btnDown.onclick = function(){
//current 항목을 밑으로 내리는것
// current.nextSibling //모든 노드를 대상으로 함
// current.nextElementSibling; //다음
// current.parentElement; //부모
// current.previousElementSibling;
// current.firstElementChild;
// current.lastElementChild;
console.log(current); //a
let next = current.nextElementSibling;
console.log(next); //b
//새로운놈, 여기에 (b에다가 a를 넣음)
let oldone = ul.replaceChild(next, current);
current = next; // b를 a에 넣음 현재갱신
// let next2 = current.nextElementSibling;
ul.appendChild(oldone); //
}
아래로 내려가긴하는데 한번에 여러칸이 다 내려가버린다.
그런데 replaceChild()는 노드와 관련된거야!
이런경우 직접 레퍼런스 찾고나서 해야한다.
after()을 쓰면된다.
current.nextElementSibling.after(current);
이거 한줄이면 충분하다!
3) insertAdjacentElement 이용하기
btnUp.onclick = function(){
let next = current.previousElementSibling;
next.insertAdjacentElement('beforebegin', current);
}
btnDown.onclick = function(){
let next = current.nextElementSibling;
next.insertAdjacentElement('afterend', current);
}
앞에 next 가 타겟이다
current가 넣을 녀석
'afterend' 는 삽입위치이다.
여기서 삽입위치를 조심해야한다
만약에 beforeend를 하면은 앞부분 li태그가 끝나기전에 삽입이된다. 결국 a,b는 하나가 되어버린다.
(5) 이벤트
1) 이벤트의 종류
다양한 이벤트 들이 있다 이벤트는 기존이벤트와 커스텀 입데이트들을 만들 수있어
관심있게 볼것은 target ,currentTarget ,cancelable 등이 있어
2) target 과 currentTarget의 차이점
이러한 이벤트를 다룰 때는 레퍼런스 참고해서 사용이 가능해 이벤트에서 타켓이 용이하게 이용이 가능하다
1. 보충
(1)
2. 회고
1)
dom 에 대해서 생명주기로서 조작할 수있는점이 흥미롭다
2달전에 볼 때와 지금와서 다시보니 받아들여지는것이 다르니 내가 성장했긴하구나 싶은 생각된다.
2)
오늘도 promise()설명을 들으면서 그 필요성을 알게되었고 이에연결되는 XHR방식 대신에 fetch가 사용되는 이유를 알게되었다.
'배움 __IL > TIL 1기' 카테고리의 다른 글
TIL : 97번째- 230425 [4-4-화] (1) | 2023.04.25 |
---|---|
TIL : 95번째- 230421 [4-3-금] (0) | 2023.04.21 |
TIL : 93번째- 230419 [4-3-수] (4) | 2023.04.19 |
TIL : 92번째- 230418 [4-3-화] (0) | 2023.04.18 |
TIL : 91번째- 230417 [4-3-월] (0) | 2023.04.17 |