오늘은 배웠던 JS로 HTML를 제어하는 방법을 터득할 것이다!
- Document Object Model
- HTML 요소를 JS Object처럼 조작(Manipulation)할 수 있는 Model
즉 JS로 HTML을 조작하기!- DOM이라는 규칙을 통해 브라우저는 렌더링, 웹 구현
<script>
라는 태그로 스크립팅 언어(JS, DOM)을 불러옴<script>
를 '어디에 써주는 가'가 중요함defer
써주면 되긴 함;;
console.dir(document.El)
: 해당 태그(요소), ID, Class를 불러와 콘솔창에 띄우는 것! 객체 데이터를 불러오는 거에서 착안- 배열 데이터 반환, 정확히는 배열과 비슷한 걸 반환
- 이 이미지는 결괏값을 보여줌, 아래
Children
에 자식 요소 있음- 아래 요소를 더 불러오고 싶으면 배열로서 불러와야함, 자주 봐야한다면 변수 지정
JS든 DOM이든 부모 요소 안 자식 요소 안 그 자식요소...의 구조를 띔, 즉 트리 구조이므로 구조를 파악, 쭉 써가면 됨
function consoleLogAllElement(element){
// nav의 class 이름을 console.log 합니다.
// nav의 자식 엘리먼트가 있는지 검색합니다. (logo, menu-wrapper)
// logo의 class 이름을 console.log 합니다.
// logo의 자식 엘리먼트가 있는지 검색합니다. (없음)
// menu-wrapper의 class 이름을 console.log 합니다.
// menu-wrapper의 자식 엘리먼트가 있는지 검색합니다. (menu, menu, menu, profile-photo)
// 첫 번째 menu의 class 이름을 console.log 합니다.
// 첫 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
// 두 번째 menu의 class 이름을 console.log 합니다.
// 두 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
// 세 번째 menu의 class 이름을 console.log 합니다.
// 세 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
// profile-photo의 class 이름을 console.log 합니다.
// profile-photo의 자식 엘리먼트가 있는지 검색합니다 (없음)
// 자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료됩니다.
// 자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료됩니다.
}
그냥 읽어보고 구조가 이렇구나~ 하며 생각하면 됨
innerHTML
과 textContent
의 차이를 이해한다.createDocumentFragment
를 활용하여, 더 효율적으로 DOM을 제어element
와 node
의 차이를 이해children
과 childNodes
의 차이를 이해remove
와 removeChild
의 차이를 이해appendChild
하면, 기존 엘리먼트를 복사할까?offsetTop
등을 이용하여 좌표 정보를 조회offsetWidth
등을 이용하여 크기 정보를 조회JS 같은 스크립팅 언어로 HTML을 조작해보자!
element = document.~
요소를 만듦, 만들기만 해서 옮겨줘야함
let Vari = document.createElement('요소')
append
붙여 옮김body
가 아닌 그 하위 요소라면 새로 변수에 그 경로를 넣어 해줘야함`document.body.append(Vari)
궁금함 더 쉬운 방법이 뭐지?
생성한 tweetDiv 를 container 에 넣기 위해서는, container 를 먼저 찾아야 합니다. 어떻게 container 를 찾을 수 있을까요? 위에서 언급했던 DOM 트리를 순회해서 찾을 수 있습니다. 그러나 보다 더 편리한 방법이 있으니 검색해 보시기 바랍니다.
querySelector()
,querySelectorAll()
.
이나#
으로 Class, Id를 불러올 수 있음getElementById()
,getElementsByClassName()
Id에는 Id만 ClassName에는 Class만 불러올 수 있음
getElementById()
를 쓰고 클래스나 다른 선택자를 쓰고 싶음 querySelector()
를 쓰자+ NodeList와 HTMLCollection 복습 필수!
만들었던, 가져왔던 변수(요소)들을 이제 수정해보자
element.textContent = "내용"
: 요소의 Value(내용) 수정element.classList.add("Class")
: 요소에 클래스 추가(多)element.setAttribute('attributename', 'attributevalue')
: 요소에 속성 추가(placeholder
, title
등)element.remove()
: 저장했던 요소의 변수를 입력해 없애버림!element.innerHTML
로 다중으로 삭제 가능하지만 보안상 안씀, 쓰지 않는 걸 권장, 그래서 querySelectorAll()
+ forEach
나 while
로 반복해 전체 삭제를 해주면 됨// 자식을 while로 삭제
const container = document.querySelector('#container');
while (container.children.length > 1) { // 하나빼고 모든 자식 삭제
container.removeChild(container.lastChild);
}
// 그 자식인 .tweet을 직접적으로 삭제
const tweets = document.querySelectorAll('.tweet')
tweets.forEach(function(tweet){
tweet.remove();
})
과제로 '유효성 검사'의 최소한의 기능을 구현함
<body>
<main>
<img class="logo" src="./images/codestates-logo.png" alt="CODE_STATES_LOGO" />
<fieldset>
<input type="text" id="username" placeholder="아이디" />
</fieldset>
<!-- 클래스 2개 설정, 띄어쓰기 -->
<div class="success-message hide">사용할 수 있는 아이디입니다.</div>
<div class="failure-message hide">아이디는 네 글자 이상이어야 합니다.</div>
<fieldset>
<input type="password" id="password" placeholder="비밀번호" />
</fieldset>
<fieldset>
<input type="password" id="password-retype" placeholder="비밀번호 확인" />
</fieldset>
<div class="mismatch-message hide">비밀번호가 일치하지 않습니다.</div>
<fieldset class="signup">
<button type="button" class="signup-button">회원가입</button>
</fieldset>
<script src="./script.js"></script>
</main>
let elInputUsername = document.getElementById("username");
let elFailureMassage = document.querySelector(".failure-message");
let elSuccessMassage = document.querySelector(".success-message");
let elPassword1 = document.getElementById("password");
let elPassword2 = document.getElementById("password-retype");
let elMismachMessage = document.querySelector(".mismatch-message");
let signButton = document.querySelector(".signup-button");
// ID 성공 메세지 출력, 실패 메세지 가림
function isMoreThan4Length(value) {
// return과 비교연산자로 불린데이터 반환하는 함수 제작
return value.length >= 4;
}
// DOM의 프로퍼티로 추가하는 거면 on+이벤트를 붙여 메소드처럼 사용 가능
elInputUsername.onkeyup = function () {
if (isMoreThan4Length(elInputUsername.value)) {
elSuccessMassage.classList.remove("hide");
elFailureMassage.classList.add("hide");
} else {
elSuccessMassage.classList.add("hide");
elFailureMassage.classList.remove("hide");
}
};
+ keyup은 JS에 내장돼 있는 '이벤트'임, 사이트 들어가서 이런 게 있구나 하고 함 보기
// 유효성 검사
function isMatch(password1, password2) {
return password1 === password2;
}
// elPassword2.addEventListner("keyup", () => {}): 리스너
elPassword2.onkeyup = function () { // 핸들러
// value 중요!
if (isMatch(elPassword1.value, elPassword2.value)) {
elMismachMessage.classList.add("hide");
} else {
elMismachMessage.classList.remove("hide");
}
};
여기서 포인트는 요소에 .value
를 붙여 요소 자체가 아닌 그 값, 내용을 isMatch
의 파라미터로 지정했음! 그 차이를 알아야함
onclick
에 직접 할당하는 것과 addEventListener
의 차이를 이해한다.eventHandler
함수를 만들고, eventHandler
의 첫 번째 인자를 사용할 수 있다.let menus = document.querySelectorAll("button"); //모든 버튼을 가져옵니다.
let btnAmericano = menus[0];
let btnCaffelatte = menus[1];
function handleClick() {
// 아래의 빈 칸(____)을 채우세요.
// console.log("working?");
let currentMenu = ____; // TODO
console.log(currentMenu + "를 클릭하셨습니다.");
}
btnAmericano.onclick = handleClick;
btnCaffelatte.onclick = handleClick; // 이상으로 for 문으로 충분히 구현할 수 있는 내용입니다.
근데 이거 하는데 뭔소린지 모르겠음 let currentMenu
에 뭔갈 채우라는데 value 쓰니까 안나옴
function handleClick(event) {
console.log("working?");
let currentMenu = event.target.textContent; // 파라미터, 타겟, 내용
console.log(currentMenu + "를 클릭하셨습니다.");
}
target
: 실제 이벤트가 일어나고 있는 요소를 선택, 상대적임textContent
를 썼음, input
태그 같은 입력되는 것은 value
로 쓰는 것이 맞음, 참고<div>
<div>hello</div>
<div id="world">world</div>
<span id="code">code</span>
<span>states</span>
<button id="apply">apply</button>
</div>
// 핸들러: 하나의 이벤트만
function displayAlert() {
alert("코드스테이츠에 오신 것을 환영합니다");
}
document.querySelector("#apply").onclick = displayAlert;
// 리스너
document.querySelector("#apply").addEventListener("click", function () {
alert("코드스테이츠에 오신 것을 환영합니다");
});
onclick 이벤트에 함수를 할당해줬는데 호출문(실행문)이 아니라!!! 함수 자체를 할당해야줘함!
+ Git Convention 보고 따라하자, 기능 단위로 쪼개 커밋, 컨벤션에 맞게 로그 남기기