<script src="myScriptFile.js"></script>
→ **<script>**
요소는 등장과 함께 실행된다.
<head>
태그에 위치
**document.onload**
와 같은 로드 이벤트가 추가되야 에러없이 작동한다.
<body>
태그가 끝나기전 하단에 위치
<body>
하단에 스크립트 태그를 넣어주는 경우로 → DOM구조가 완료된 시점에 실행되어 별다른 추가 설정이 필요없다.
**async
속성 사용**
<head>
에<script>
를async
속성과 함께 사용한다.
<script async src="scripy.js></script>
파싱과 JS 불러오기를 병렬로 진행 → 다운받는 시간이 절약된다.
주의점 : **async
** 속성은 script 태그 선언 순서와 상관없이 다운 받아지는 순서대로 js파일을 실행한다.
→ 따라서 순서에 의존적인 페이지라면 문제가 될 수 있음으로 주의
defer
속성 사용
<head>
에<script>
를defer
속성과 함께 사용한다.
<script defer src="scripy.js></script>
**async
속성과 달리 JS파일을 다운받고 파싱이 끝난후 순서대로 JS 파일을 실행** → 원하는 방향대로 스크립트를 실행할 수 있다,참고 자료
nav
, news-contents
, footer
를 조회하고 싶다면?<html>
<body>
**<div id="nav">**
<div class="logo"></div>
<div class="menu-wrapper">
<div class="menu">menu</div>
<div class="menu">menu</div>
<div class="menu">menu</div>
<div class="profile-photo">photo</div>
</div>
</div>
**<div id="news-contents">**
<div class="news-content-wrapper">
<div class="news-picture">news-picture</div>
<div class="news-title">news-title</div>
<div class="news-description">news-description</div>
</div>
</div>
**<div id="footer">footer</div>**
</body>
</html>
<document>
객체에 구현되어 있다.<document>
객체를 조회할 수 있다.//1. body안의 모든 요소를 찾고 싶다면
console.dir(document.boby)
//2. body안의 자식요소를 찾고 싶다면
console.dir(document.body.children)
//3. body안의 첫번째 자식요소를 찾고 싶다면
console.dir(document.body.children[1])
//4. 변수 선언
console.dir(document.body.children[1])
div#news-contents
let newCon = document.body.children[1];
newCon; // <div id = "news=contents"> ...
DOM 요소 검색 키워드
children
: 자식 요소firstElementChild
,lastElementChild
: 첫 번째 및 마지막 자식 요소previousElementSibling
,nextElementSibling
: 형제 요소(태그만)parentElement
: 상위 부모 요소(태그만)parentNode
: 부모 요소(노드 전체)
Node(노드) 와 element(요소) 차이점
CREATE
<div>
요소 만들기document.createElement('div') //<div></div>
div
element에 변수 tweetDiv
할당하기const tweetDiv = document.createElement('div') //undefined
tweetDiv
는 body와 연결되어있지 않다(공중부양 상태)append
메소드로 변수tweetDiv
를 <body>
에 넣기document.body.append(tweetDiv) //undefined
<body>
안에 textcontext
없이 있는 상태 → 화면엔 보이지 않는다.READ
HTML요소
(’div’), id
(’#tweetList), class
(.tweet)가 가장 많이 사용된다.querySelector
에 '.tweet'
을 첫 번째 인자로 넣으면, 클래스 이름이 tweet
인 HTML 엘리먼트 중 첫 번째 엘리먼트를 조회//querySelector로 클래스 이름이 tweet인 HTML 요소를 조회
const oneTweet = document.querySelector('.tweet')
//querySelectorAll로 클래스 이름이 tweet 인 모든 HTML 요소를 유사 배열로 받아온다.
const tweets = document.querySelectorAll('.tweet')
유사배열(Array-like Object)란?
querySelectorAll
로 조회한 HTML 요소들은 배열처럼 for문을 사용할 수 있다.
하지만 진짜 배열은 아니기에 이런 ‘배열아닌 배열’을 → 유사배열, 배열형 객체 등으로 부른다.
querySelector
=== getElementById
//'getElementById'는 DOM의 옛날 방식의 조회 메서드
// =querySelector와 비슷한 역할을 하는 오래된 방식(이전 버전의 호환성을 신경써야 할때 사용)
const getOneTweet = document.getElementById('container')
const queryOneTweet = document.querySelector('#container')
console.log(getOneTweet === queryOneTweet) // true
id
에 <div>
요소 넣어주기const container = document.querySelector('#container')
const tweetDiv = document.createElement('div')
//id(#container)의 맨 마지막 자식 요소로 tweetDiv를 추가
container.append(tweetDiv)
value
속성 사용//<input type="text" id="username">의 값을 가져오려면, 다음과 같이 접근
console.log(document.querySelector('#username').value);
document.querySelector('#username').value = '새로운 값
UPDATE
oneDiv
라는 이름의 <div>
요소 만들기const oneDiv = document.createElement('div'); // <div></div>
textContent
로 div
엘리먼트에 문자열 입력하기oneDiv.textContent = 'dev'; //<div>dev</div>
class
를 추가 (기존 CSS 스타일링 동일 적용된다)oneDiv.classList.add('tweet') //<div class="tweet">dev</div>
append
를 이용해 id(#container)의 자식요소로 추가const container = document.querySelector('#container')
container.append(oneDiv)
class와 id 말고 다른 attribute를 추가하려면? setAttribute
→
aElement**.setAttribute('id', 'javascript')**
DELETE
remove
메서드//id가 container인 요소 아래에 tweetDiv를 추가하고, remove로 삭제하는 코드
const container = document.querySelector('#container')
const tweetDiv = document.createElement('div')
container.append(tweetDiv)
tweetDiv.remove() // append 했던 요소를 삭제할 수 있다.
innerHTML
메서드//id가 container인 요소 아래의 모든 요소를 지운다.
document.querySelector('#container').innerHTML = '';
innerHTML
메서드는 간편하지만 여러 보안상의 문제를 가진다. 따라서 대신할 아래 메서드들의 활용을 추천한다.removeChild
메서드예제1 : 자식 요소가 남지않을 때까지 첫번째 자식 요소를 삭제한다.
🚫 removeChild
와 while
을 이용해 자식 요소를 삭제하면 → 제목에 해당하는 H2 "Tweet List"까지 삭제된다.
//container의 첫 번째 자식 요소가 존재하면, 첫 번째 자식 요소를 제거한다.
const container = document.querySelector('#container');
while (container.firstChild) {
container.removeChild(container.firstChild);
}
방법1 : container의 자식 요소가 1개만 남을 때까지, 마지막 자식 요소를 제거
const container = document.querySelector('#container');
//1보다 작을 때는 멈추기 -> 1보다 작다는 것은 containe안에 자식요소가 없단 뜻이니까!
while (container.children.length > 1) {
container.removeChild(container.lastChild);
}
방법2 : 클래스이름이 ‘tweet’인 요소만 찾아 제거하기.
//1)
const tweets = document.querySelectorAll('.tweet')
tweets.forEach(function(tweet){
tweet.remove();
})
//2)
그 밖의 방법 :
- 새로운 변수를 생성해 제목에 해당하는 H2 "Tweet List”를 할당하고 → 반복문이 끝나면 새롭게 추가
- 자식 요소를 하나만 남기기
CSS 속성
//CSS에 다음과 같이 설정
//나타내고 싶다면 'block'
.hide {
display: none;
}
: 자바스크립트를 이용해 스타일을 직접 조작하지 않고 → CSS 클래스를 이용해 간접적으로 바꾸는 것(그리고 이를 권장한다.)
심화학습
element
와 node
의 차이를 이해할 수 있다.children
과 childNodes
의 차이를 이해할 수 있다.remove
와 removeChild
의 차이를 이해할 수 있다.offsetTop
등을 이용하여 좌표 정보를 조회할 수 있다.offsetWidth
등을 이용하여 크기 정보를 조회할 수 있다.//1) 아이디 입력창(elInputUsername)에 글자를 키보드로 입력할 때
let elInputUsername = document.querySelector('#username') //-> 아이디 입력창
//2) 글자수가 4개 이상이면,
function isMoreThan4Length(value) {
return value.length >= 4
}
//3) '사용할 수 있는 아이디입니다' 라는 메세지가 출력된다.
let elFailureMessage = document.querySelector('.failure-message')
let elSuccessMessage = document.querySelector('.success-message')
elInputUsername.onkeyup =function() {
if(isMoreThan4Length(elInputUsername.value)) {
//성공 메세지가 보여지고
elSuccessMessage.classList.remove('hide')
//실패 메세지가 가려져야함
elFailureMessage.classList.add('hide')
} else {
//성공 메세지가 가려지고
elSuccessMessage.classList.add('hide')
//실패 메세지가 보여져야함
elFailureMessage.classList.remove('hide')
}
}
let elInputPassword = document.querySelector('#password')
let elInputRetypePassword = document.querySelector('#password-retype')
let elMissmatchMessage = document.querySelector('.mismatch-message');
//1)비밀번호의 value와 비밀번호 확인의 value가 일치하다면,
function isMatch(password1, password2){
return password1 == password2;
}
//2.비밀번호 확인 창에 입력했을 때,
elInputRetypePassword.onkeyup= function() {
if(isMatch(elInputPassword.value, elInputRetypePassword.value)){
//실패 메세지 가려진다.
elMissmatchMessage.classList.add('hide');
} else {
//틀리면 실패 메세지가 보인다
elMissmatchMessage.classList.remove('hide');
}
}
//! 내가 놓쳤던 것! //
// -> 비밀번호, 비밀번호 확인의 값을 비교하는게 아니라 -> 비밀번호의 value와 비밀번호 확인의 value를 비교해야한다.
//즉 value를 빼먹음! -> 명심하자 ~!
이벤트 : DOM에서 마우스를 클릭하거나, 키보드를 누르는 등의 사용자 액션에 의해 발생한다.
- 브라우저 창 크기를 조절하거나, 스크롤 하는것도 DOM 이벤트의 일종이다.
- 이벤트와 관련된 속성은
**on**
이라는 접두어가 붙는다(onclick
,onkeyup
등)
이벤트 핸들러 : 이벤트가 발생할 때 실행되는 함수
두 개의 버튼을 클릭할 때, 각각 아메리카노를 클릭하셨습니다.
또는 카페라떼를 클릭하셨습니다
라고 출력
let menus = document.querySelectorAll("button"); //모든 버튼을 가져온다.
//<button>아메리카노</button>
//<button>카페라떼</button>
let btnAmericano = menus[0];
let btnCaffelatte = menus[1];
//menus = [btnAmericano, btnCaffelatte] //각각 [0], [1]
btnAmericano.onclick = handleClick;
btnCaffelatte.onclick = handleClick; // for 문으로도 충분히 구현할 수 있는 내용임.
function handleClick() {
let currentMenu = document.querySelector('menus')
console.log(currentMenu + "를 클릭하셨습니다.");
}
event
객체에는 어떤 내용이 출력되는가?event.target
은 어떤 값을 담고 있는가?Q. 어떤 버튼(btn
)이 존재하고, 버튼을 클릭할 때 콘솔에 "버튼이 눌렸습니다!"를 출력하고 싶다면?
//1) 오답 : onClick -> onclick
btn.onClick = function() {
console.log('버튼이 눌렸습니다!');
}
//2) 정답
btn.onclick = function() {
console.log('버튼이 눌렸습니다!');
}
//3) 정답
btn.addEventListener('click', function() {
console.log('버튼이 눌렸습니다!');
});
//4)정답
function handler() {
console.log('버튼이 눌렸습니다!');
}
btn.onclick = handler;
//5) 오답 : 이벤트 속성(onclick(을 이벤트 핸들러에 등록할 땐 ->
// 함수의 실행을 등록(x) -> 함수 그 자체로 등록해야 한다.
function handler() {
console.log('버튼이 눌렸습니다!');
}
btn.onclick = handler(); //handler로 수정(함수 그 자체로 등록)
메소드
insertAfter() 메서드
: 선택한 요소 뒤에 HTML 요소를 삽입한다.
insertBefore() 메소드
: 선택한 요소 앞에 HTML 요소를 삽입한다.
원하는 노드.cloneNode()
: 노드 복제를 복제하는 메소드
원하는 노드.cloneNode(true);
**.appendChild(aElement)**
:
**.prependChild(aElement)**
:
**document.importNode**
: template 을 활용하여 내용을 붙여 넣을 때 사용하는 메서드
조회
**document.querySelector('div')**
: 최상단 <div>
요소 하나만 조회
**document.getElementById('div')**
: id가 <div>
요소 하나를 조회
**document.getElementsByClassName('div')
:** class가 <div>
요소 여러개를 조회
document.querySelectorAll('div')
, document.getElementsByTagName('div')
: <div>
요소 모두 조회 삭제
엘리먼트 삭제
document.querySelector("#world").remove()
, document.querySelector("#world").remove(aElement)
Q. 아이디가 "javascript"이고, 내용이 "awesome"인 <a>
요소를 생성하는 방법 2가지
//1.
let aElement = document.createElement('a')
aElement.setAttribute('id', 'javascript')
aElement.textContent = 'awesome'
//2. 하지만 innerHTML 사용은 왠만하면 지양된다.
let aElement = document.createElement('a')
aElement.id = 'javascript'
aElement.innerHTML = 'awesome'