html에 접근하여 문서를 변경할때 접근법을 생략하지 않고 모두표기했을때 예시↓
<!DOCTYPE html>
<html lang="kor">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Advanced JavaScript</title>
<script src="app.js" defer></script>
</head>
<body>
<h1>Hi there!</h1>
<p>
This is a
<a href="#">link</a>
</p>
</body>
</html>
// console.dir(document); // 문서의 구조를 javascript로 볼 수 있는 명령어
document.body.children[1].children[0].href = 'https://google.com'; // anchor태그에 접근하여 링크주소를 google.com으로 변경. html의 중첩구조를 이용하여 접근함.(=DOM을 이용하기 위해서는 정확한 구조를 알고있어야 함)
브라우저 console창에서 document.body.firstElementChild
입력
출력결과: <h1>Hi there!</h1>
텍스트 요소의 경우 줄바꿈, 공백까지 모두 해당 태그의 content로 포함됨에 유의.
document.getElementById('id이름');
예시 (상단의 dom 예시를 getElementById메서드로 접근하도록 변경)
let anchorElement = document.getElementById('external-link');
anchorElement.href = 'https://google.com';
querySelectorAll
으로 해당하는 객체 전체선택도 가능. (querySelector
는 단일객체용)document.querySelector('#id이름');
예시 (상단의 dom 예시를 querySelector메서드로 접근하도록 변경)
anchorElement = document.querySelector('#external-link');
anchorElement.href = 'https://www.naver.com';
getElementsByClassName('some-css-class')
: 해당 css클래스가 있는 모든 html요소를 선택함.getElementsByTagName('tag')
: 해당 html태그 유형의 모든 html요소를 선택예시 (html문서는 위의 문서 그대로 사용)
// html객체에 새로운 요소 추가하기
// 1. 새로운 객체 생성
let newAnchorElement = document.createElement('a');
newAnchorElement.href = 'https://google.com';
newAnchorElement.textContent = ' This leads to Google!';
// 2. 부모요소에 접근
let firstParagraph = document.querySelector('p');
// 3. 부모요소 컨텐츠에 요소 추가
firstParagraph.append(newAnchorElement);
예시 (html문서는 위의 문서 그대로 사용)
// html객체의 요소 삭제하기
// 1. 삭제할 요소 선택
let firstH1Element = document.querySelector('h1');
// 2. 요소 삭제 (둘 중 택1)
firstH1Element.remove(); // 구버전 웹브라우저에서는 사용불가
firstH1Element.parentElement.removeChild(firstH1Element); // 구버전에도 사용가능한 코드
textContent
: 개체가 가진 텍스트값만 선택innerHTML
: html태그를 포함한 개체 내 모든값을 선택console.log('textContent: ' + firstParagraph.textContent);
console.log('innerHTML: ' + firstParagraph.innerHTML);
// 출력결과
textContent: I'm new! This leads to Google!
innerHTML: I'm new!<a href="https://google.com"> This leads to Google!</a>
예제
<input type="text" />
// input태그 키입력이벤트
let inputElement = document.querySelector('input');
function retriedveUserInput() {
let enteredText = inputElement.value;
console.log(enteredText);
}
inputElement.addEventListener('keydown', retriedveUserInput);
=> input창에 입력한 값이 console에 출력된다.
함수 이벤트 작성 시 주의점
이벤트작성 시 위의 예제에서
inputElement.addEventListener('keydown', retriedveUserInput);
는keydown
이벤트가 일어날 때 함수retriedveUserInput
를 실행시키라는 것을 의미하는 부분이다.
이때 함수의 이름에()
를 붙여inputElement.addEventListener('keydown', retriedveUserInput());
라고 작성하였을 경우 이 구문이 해석되자마자 바로retriedveUserInput
함수가 실행되어버리니 주의하여 작성하자.
상수는 값을 변경할 수 없는 변수.
=> 단, 객체를 상수에 넣은 후 객체의 속성을 바꾸는 것은 가능함.(객체를 바꾸는 것은 불가능)
아래의 예시 참고.
- index.html -
<script defer src="ex.js"></script>
...
<form action="submit">
<div class="control">
<label for="product-name">Product Name</label>
<input type="text" id="product-name" name="product-name" maxlength="60" />
<span id="charcount"> <span id="remaining-chars">60</span>/60 </span>
</div>
<button>Submit</button>
</form>
- ex.js -
const inputElement = document.getElementById('product-name');
const remainingElement = document.getElementById('remaining-chars');
const maxAllowedChars = inputElement.maxLength;
function updateRemainingCharacters(event) {
const enteredText = event.target.value;
const enteredTextLength = enteredText.length;
console.log(enteredTextLength);
const remainingCharacters = maxAllowedChars - enteredTextLength;
remainingElement.textContent = remainingCharacters;
}
inputElement.addEventListener('input', updateRemainingCharacters);
60자 제한이 있는 input창에 입력할 수 있는 잔여글자수를 실시간으로 출력하는 예제.
남은 잔여글자수를 보여주는 <span>
태그객체를 상수 remainingElement
에 담은 후 remainingElement.textContent = remainingCharacters
를 통해 객체의 텍스트속성을 변경한다.
이때 객체의 속성을 변경하지만 상수에 담긴 '객체'를 변경한 것은 아니기 때문에 에러가 발생하지 않는다.
=> 상수에 대한 개념에서 이 점을 유의하자.
.className
메서드로 특정 태그에 클래스를 줄 수 있다.const spanElement = document.getElementById('remaining-chars');
spanElement.className = 'warning';
.className
을 통해 클래스를 설정할 경우 원래 가지고 있던 클래스는 삭제되고 새로 설정한 클래스만 남게 되므로 주의.const spanElement = document.getElementById('remaining-chars');
spanElement.className = 'warning some-class';
// warning, some-class 총 2개의 클래스를 한번에 설정해줌
className
와 달리 특정 클래스를 추가하거나 삭제하는 메서드.const spanElement = document.getElementById('remaining-chars');
spanElement.classList.add = 'warning';
// => 원래 설정되어 있던 클래스에 warning클래스가 추가됨
spanElement.classList.remove = 'warning';
// => warning클래스가 삭제됨 (가지고 있던 다른 클래스에는 영향x)
예제
- index.html -
<body>
<h1>Advanced JavaScript</h1>
<p>DOM 관련 작업 - 연습</p>
<section>
<h2>왜 JavaScript인가?</h2>
<p>JavaScript는 페이지가 로드된 후 브라우저에서 실행할 수 있는 프로그래밍 언어입니다.</p>
<p>JavaScript를 사용하면 개발자가 구문 분석된 HTML 코드("DOM")에 액세스, 읽기 및 조작하여 페이지에 추가 동작 및 기능을 추가할 수 있습니다.</p>
<p>예를 들어, 아래 단추를 사용하여 이 텍스트를 제거할 수 있습니다!</p>
<button>Remove Paragraph</button>
<p>또는 다음 버튼을 누릅니다: 첫 번째 단락에 파란색 배경을 추가합니다.</p>
<button id="backgroundColorChangeBtn">Add Blue Background Color</button>
</section>
</body>
- exercise.js -
const removeBtn = document.querySelector('button');
const backgroundColorChangeBtn = document.getElementById('backgroundColorChangeBtn');
const firstParagraphElement = document.body.children[2].children[1];
const tghirdParagraphElement = firstParagraphElement.nextElementSibling.nextElementSibling;
function clickRemoveBtn() {
tghirdParagraphElement.remove();
}
function changeBackgroundColor() {
// firstParagraphElement.style.backgroundColor == 'skyblue'
const elementClassName = firstParagraphElement.className;
console.log(firstParagraphElement.className);
if (elementClassName == 'blue-bg') {
firstParagraphElement.className = '';
} else {
firstParagraphElement.className = 'blue-bg';
}
}
removeBtn.addEventListener('click', clickRemoveBtn);
backgroundColorChangeBtn.addEventListener('click', changeBackgroundColor);
=> 두 버튼을 차례로 클릭했을때 결과