DOM 이란 무엇인가?
- Document Object Model 의 약자이다.
- HTML 요소를 Object처럼 조작 할 수 있는 Model이다.
Achievement Goals
- DOM의 개념을 이해할 수 있다.
- DOM의 구조를 파악하고, HTML과 DOM이 어떻게 닮아있는지 알 수 있다.
- HTML에서 Javascript 파일을 불러올 때 주의점에 대해서 이해할 수 있다.
- <script> 태그가 적용되는 위치에 따라서 실행 결과가 달라질 수 있음을 이해할 수 있다.
DOM으로 HTML 조작하기
CREATE - createElement
const tweetDiv = document.createElement('div')
위와 같은 명령어를 쳐도 화면에는 변화가 없습니다.
div가 생기긴 했지만 아무것도 연결이 되어있지 않기 때문에 따로 떨어져 있습니다.
그래서 APPEND를 이용해서 웹 페이지 상에도 보이게 해야 합니다.
APPEND -append, appendChild
document.body.append(tweetDiv)
위와 같은 명령어를 입력하면 역시 웹 페이지에 아무것도 나오지 않습니다.
이 것은 개발자도구에서 확인하면 새로운 div가 생긴 것을 확인할 수 있지만 안에 아무런 내용이 없기 때문입니다.
그래서 UPDATE를 통해서 내용을 입력할 수 있습니다.
또한 우리가 원하는 위치에 생성한 div를 넣기 위해서는 container를 먼저 찾아야 합니다.
READ를 통해서 container를 찾을 수 있습니다.
READ - querySelector, querySelectorAll
const oneTweet = document.querySelector('.tweet')
위와 같은 명령어를 입력하면 클래스 이름이 tweet 인 HTML 엘리먼트 중 첫 번째 엘리먼트를 조회할 수 있습니다.
여러 개의 엘리먼트를 한 번에 가져오기 위해서는 querySelectorAll 을 사용합니다.
const tweets = document.querySelectorAll('.tweet')
오래된 방식의 get으로 시작하는 명령어도 있다. (getElementById, getElementByClassName, getElementByName 등)
const container = document.querySelector('#container')
container.append(tweetDiv)
위와 같이 입력하면 새로만든 div가 원하는 위치인 container 안에 들어가는 것을 확인할 수 있습니다.
UPDATE - textContent, classList.add
console.log(tweetDiv)
tweetDiv.textContent = 'div';
console.log(tweetDiv)
위와 같이 입력하면 새로만든 div에 dev라고 입력할 수 있다.
하지만 아직 CSS 스타일링이 적용되지 않았기 때문에 class를 추가해서 CSS가 적용될 수 있도록 해야한다.
tweetDiv.classList.add('tweet')
console.log(oneDiv)
class와 id 말고 다른 attribute를 추가하고 싶을 때는 setAttribute 라는 메소드를 사용한다.
Delete - remove, removeChild
tweetDiv.remove()
위와 같은 명령어를 치면 생성한 div가 사라지는 것을 확인할 수 있습니다.
여러개의 자식 엘리먼트를 지우기 위해서는 innerHTML을 이용할 수 있습니다.
document.querySelector('#container').innerHTML = '';
위와 같은 방식은 편하긴 하지만 보안에서 몇가지 문제를 가지고 있습니다.
대표적인 XSS(Cross-Site Scripting) 공격에 취약합니다. 이는 권한이 없는 사용자가 악의적인 용도로 웹 사이트에 스크립트를 삽입하는 공격 기법을 말합니다.
※ XSS의 공격 순서
1. 해커가 사전에 만든 웹페이지에 사용자가 브라우저로 엑세스를 시도
2. XSS공격 link가 포함된 웹페이지가 브라우저에 표시
3. 사용자가 link를 클릭
4. 사용자가 느끼지 못하는 사이 취약한 사이트에 있는 해커의 스크립트에 엑세스 됨
5. 사용자의 웹브라우저 상에서 해커의 스크립트가 실행
removeChild 명령어를 반복문과 같이 활용해서 모든 자식 엘리먼트를 삭제할 수 있습니다.
while (container.firstChild) {
container.removeChild(container.firstChild);
}
하지만 위와 같이 입력하면 원하지 않은 Tweet List 까지 삭제되는 것을 볼 수 있습니다.
이것을 방지하기 위한 방법으로는 아래와 같습니다.
while (container.children.length > 1) {
container.removeChild(container.lastChild);
}
아니면 클래스 이름이 tweet인 엘리먼트들만 찾아서 지우는 방법도 있습니다.
const tweets = document.querySelectorAll('.tweet')
for (let tweet of tweets) {
tweet.remove()
}