
JavaScript를 이용해서 HTML 엘리먼트의 속성값을 얻어내거나 변경하는 방법
DOM은 웹 페이지의 객체 지향적인 표현이다.
자바스크립트와 같은 스크립팅 언어를 이용해 DOM 을 수정할 수 있다.
HTML 마크업 파싱 -> DOM 트리 빌드
CSS 마크업 파싱 -> CSSOM (CSS객체모델) 트리 빌드
DOM 및 CSSOM의 결합 => 렌더링 트리 생성
렌더링 트리에서 레이아웃을 실행 -> 각각의 노드들의 레이아웃을 계산 ->
노드들을 화면에 렌더링
<body>
<div id='practice' class='highlight red'>
여기 엘리먼트가 하나 있습니다
<span>ㅇㅇㅇ</span>
<span>ㅋㅋ</span>
</div>
</body>
속성: <>안에 태그 이름과 같이 정의되어 있는 것
태그이름: body, div, span
id: practice
class: highlight, red
안쪽에 담긴 내용: 여기 엘리먼트가 하나 있습니다, ㅇㅇㅇ, ㅋㅋ
div#practice 에 대하여
부모엘리먼트: body
자식엘리먼트: span, span
html은 tree구조를 갖는다.
javascript에서 tree구조를 갖는 것은 객체 Object
key의 값value으로 또 다른 object(배열 & 객체)를 가질 수 있다.
🚫 DOM이 JavaScript는 아니다.
DOM 구조 접근에 JavaScript를 이용한다는 것이다.
따라서 DOM:Document Object Model이란?
📌 HTML 문서의 구조와 관계를 객체(Object)로 표현한 것
document라는 전역변수로 접근이 가능{ tagName: 'DIV', id: 'practice', classList: ['highlight', 'red'], textContent: '여기 엘리먼트가 하나 있습니다 ㅇㅇㅇ ㅋㅋ', parentElement: body, children: [ {tagname: 'SPAN', textContent: 'ㅇㅇㅇ' }, {tagname: 'SPAN', textContent: 'ㅋㅋ' } ] }
console.log(document);
// html이 구조로 나옴 `<head><body>...`
console.dir(document);
// element를 확인할 수 있는 방법, html이 object처럼 나옴
// charset:~~이 궁금하다면? 실제로 js에서 찍어볼 수 있다.
document.charset; //'UTF-8'

$0은 크롬개발자도구 콘솔창에서 HTML속성을 확인해볼 수 있는 방법이다.
코드 내에서 아래 키워드들로 속성을 확인하려면, 해당 엘리먼트를 변수로 선택하고(🔎 특정 element를 선택하고 가져오는 법)
console.log(변수명)/ console.dir(변수명) 하면 된다.
태그이름 tagName : $0.tagName
id selector : $0.id
class목록 classList :$0.classList
class문자열 className : $0.className
속성 객체 attributes : $0.attributes
<div class='contents'> 안녕 ???</div> ==$0
innerText 비교적 사용이 적음 안녕 ???
실제로 화면에 랜더링되는 text들이 보여짐
엘리먼트에 담긴 내용 innerHTML : $0.innerHTML
HTML요소의 값을 바꾸거나 값을 넣을 때
값을 할당할 수 있고 실제로 화면의 내용을 바꿀 수 있다.
화면에 실제로 해당태그위치에
$0.innerHTML="<a href = 'https://velog.io'>벨로그</a>"하면
벨로그가 된다
부모태그에서 사용시 관련tags<> 가 전체적으로 보여짐
엘리먼트에 담긴 내용 textContent : $0.textContent 안녕 ???
하나의 단일 element에 내용을 채워넣을 때 사용
값을 할당할 수 있고 실제로 화면의 내용을 바꿀 수 있다.
innerHTML과의 차이점은
$0.textContent="<a href = 'https://velog.io'>벨로그</a>"하면
위의 태그가 그대로 화면에 문자열 자체로 추가된다.
랜더링된 화면이 아니라 실제 포함되어있는 공백까지 텍스트와함께 보여짐
value: $0.value
form 입력 값을 얻을 수 있다.
form 입력창 =>id입력창,댓글입력창,input,textarea,,,에 입력값이 들어오면 $0.value를 통해 입력값을 얻는다.
ex) twittler만들 때 새글 쓰기
부모 element parentElement : $0.parentElement
자식 element vs 자식 node
<body>
<div id = 'practice' class = 'highlight red'>
여기 엘리먼트가 하나 있습니다
<span>ㅇㅇㅇ</span>
<span>ㅋㅋ</span>
</div>
</body>
<div ~ >를 $0으로 두고 $0.textContentdataset: $0.dataset.~
태그 자체에 데이터를 담고싶을 때
화면에 보이지는 않는다.
숨겨진 데이터를 심고 싶을때 js dataset속성을 통해서 값을 얻어올 수 있다.
<div data-user='steve' data-role='moderator' data-user-id='1'>SteveLee</div>
$0.dataset.user <//'steve'
$0.dataset.role //'moderator'
$0.dataset.userId //'1'
trigger 종류
click/ mouse events/ keyboard typing/ changing current location/ 기타 등등
<button>에 $0을 두고 console.dir($0);을 통해 button tag와 관련된 속성들을 볼 수 있다.<onclick><onchange><ondoubleclick><onkeydown><onmousemove><onscroll>등등
사용법: $0.onclick에 함수를 직접 걸어주면된다.
addEventListener
function foo(){
alert('마우스가 클릭되었습니다')
}
$0.onclick = foo; //ƒ foo(){alert('마우스가 클릭되었습니다')};
//참고. 위 내용을 아래와 같이 메소드를 이용해 구현할 수도 있다
$0.addEventListener('click', function(){
alert('마우스가 클릭되었습니다')
});
해당 버튼을 클릭하면 지정한 문자열와 함께 alert창이 뜬다.
사용자의 동작에 반응하는 방법 이외에 사용자가 등록한 내용을 받아와야할 때에는??
ex)사용자가 이름, 댓글내용 입력 후 등록을 눌렀(Click)을 때 ➜ 이 때 동작할 함수 작성
함수에 $0로 할 수 있는 속성이 없다. (언제까지 $0으로만 DOM을 다룰 수가 없다)
사용자의 이름을 어떻게 변수로 받아올 것인가?
댓글 내용을 어떻게 변수로 받아올 수 있을까?
사용방법:
document.querySelectorAll('.comment')
//선택된 곳의 comment이름을 가진class를 선택
➜ NodeList라는 유사배열형태로 []에 담겨 나옴
이 유사배열을 변수에 담아서 배열처럼 호출가능
let allComments = document.querySelectorAll('.comment');
allComments[0]
querySelectorAll : 여러개의 tag선택, class를 여러개 선택할 때
📌 id값처럼 하나의 태그를 받아올 때는 querySelector사용하면 된다.
어차피 id는 1개니까 0번째까지 밖에 없으므로 굳이 배열로 받아올 필요가 없다.
Q. 사용자가 이름과 댓글을 입력했을 때 값을 받아서 값을 담은 값을 콘솔에 출력하려면?
function getInputValue(){
//user name과 comment를 선택
let eleUsername = document.querySelectorAll('#username');
let eleNewComment = document.getElementById('comment');
//username과 comment의 값을 얻어온다
Alert(eleUsername.value);
Alert(eleNewComment.value);
}
getInputValue(); //사용자가 이름과 댓글창에 입력한 값이 실행된다
//버튼을 눌렀을때 위의 동작이 실행되게 하려면?
/* <button>에 id설정을 해준 후에 (다른 button들과 겹칠 수 있으므로)
해당버튼을 <button id='register'>라고 했을때 */
document.querySelector('#register').onclick = getInputValue;
사용자의 입력값을 받아오고 받아온 값으로 이벤트 출력
그 다음
받아온 값이 화면에 설정된 형식에 맞게 출력되어야 한다.
예를 들어, 트윗을 하면 트윗 목록에 사용자명/ 트윗내용/ 날짜시간 등이 출력되어서 목록처럼 쌓여야함 ➜ **DOM을 조작해야 함
<div id="target">변경 전</div>
let target = document.querySelector('#target');
target.innerHTML = `
<span>변경 후</span>
`;
HTML출력결과
<div id="target"><span>변경 후</span></div>
.createElement('태그이름'): '태그이름'element 생성)<div id="target">변경 전</div>
let target = document.querySelector('#target');
let newSpan = document.createElement('SPAN'); //동적으로 엘리먼트 생성
newSpan.innerHTML='변경 후'; //만든span에 내용채워넣기, 단순string이라 textConten로도 넣기가능
target.appendChild(newSpan); //자식으로 넣으려는 method, 만든 span태그를 삽입
//target아래쪽에 newSpan 엘리먼트 추가
/* .appendChild()는
js를 이용해서 만든 element를 화면에 뿌려줄 수 있다(=newSpan을 target에 추가해줄 수 있다)
변경 전(=target) 아래쪽에 <span>가 담긴변수 newSpan 추가 */
<div id="target">
변경 전
<span>변경 후</span>
</div>
➕ 이해를 돕기위한 예제
목적 : 새로운 트윗 한개가 등록되면 기존에 올라와있는 트윗목록(<li class="comment">..</li>)에
새로운 트윗 하나가 더 추가되도록 하는 것
1. 먼저 새 엘리먼트 li를 만든다.
2. li에 내용을 추가한다.
3. 삽입하려는 대상(부모)엘리먼트를 선택해서 가져온다.
4. 부모엘리먼트(<div id='view-comments'>..</div>)에 새 엘리먼트 li를 추가한다.
function appendNewComment(){
let li = document.createElement('LI');
li.innerHTML = '<div class='username'>adela</div> <div class='contents'>새로운 트윗</div>' //HTML tag자체를 넣고싶을때,
//li.textContent를 사용해도 된다
let parent= document.querySelector('#view-comments')
parent.appendChild(li)
}
appendNewComment();
위 과정을 통해서 새로운 li태그들이 실행할 때마다 생겨난다.
이제 생겨난 li태그들에게 기존에 올라와있는 목록들처럼 class지정해주기
1. 위 함수에 li.className = 'comment'추가
2. 사용자 이름과 트윗내용이 달라져도 함수가 작동할 수 있게 parameter로
사용자이름과 내용을 지정하고 채울 내용에도 parameter 적용 (id, content)
function appendNewComment(id, content){
let li = document.createElement('LI');
li.className = 'comment'
li.innerHTML = '<div class='username'> + id + </div> <div class='contents'> + content + </div>' //HTML tag자체를 넣고싶을때,
//li.textContent를 사용해도 된다
let parent= document.querySelector('#view-comments')
parent.appendChild(li)
}
appendNewComment('새 사용자', '새 내용');
target.innerHTML = "" //공백문자를 넣어놓으면 삭제한다는 뜻
target.remove(); //method로 해당태그 삭제
<script>태그의 위치script.js 파일을 만들어 console.log('Hello World')를 적어 놓고
index.html이 완성되면 마지막 body태그 끝나기 직전에
<script src="script.js"></script>
꼭 body태그가 닫히기 직전에 해줘야 DOM에 접근할 수 있다.
body태그 안의 요소들이 다 그려지기 전인 script태그를 맨위에 넣으면 접근이 안된다.
연결해준 후에 새로고침해보면 해당 파일이 열린 브라우저 콘솔창에 "Hello World"가 출력된다.
vanilla javascript: 어떠한 라이브러리도 쓰지않고 조작하는 javascript를 말한다.
키워드로 검색해서 필요할 때마다 찾아 쓰면 된다.
참고 element vs node
Element는 Node이다 (Node에 속해있다.)
Text는 Node이나, Element는 아니다. (문자열을 담은 객체)