오늘의 꿀팁
💡 레퍼런스 체크: 전 회사에 전화해보는 과정 -> 깽판 치고 나오면 안된다!
💡 처음 자기소개할 때 자격요건에 있는 내용 포함해서 말하기
DOM 제어
node.textContent
element.innerHTML
htmlElement.innerText
💡 innerHTML 사용시 주의 사항
사이트의 공격 경로가 되어 잠재적인 보안 위험이 발생할 수 있다.
name = "<script>alert('I am John in an annoying alert!')</script>";
el.innerHTML = name; // harmless in this case
cross-site scripting 공격처럼 보일 수 있지만 결과는 무해하다. HTML5는 innerHTML
과 함께 삽입된 <script>
태그가 실행되지 않도록 지정한다.
그러나 <script>
요소를 사용하지 않고 자바스크립트를 실행하는 방법이 있으므로 innerHTML
을 사용하여 제어할 수 없는 문자열을 설정할 때마다 여전히 보안위험이 있다.
const name = "<img src='x' onerror='alert(1)'>";
el.innerHTML = name; // shows the alert
∴ 사용자에게 입력받을 때는 textContent
를 사용해야 한다.
https://developer.mozilla.org/ko/docs/Web/API/Element/innerHTML#security_considerations
style
객체target.style.color = "red";
target.style.fontWeight = "bold";
target.style.color = null; // 현재 스타일 정보를 제거(초기화)
style 객체의 속성 식별자 규칙
height
, color
…)background-image
⇒ backgroundImage
)float
속성의 경우 이미 자바스크립트의 예약어로 존재하기 때문에 cssFloat
으로 사용한다💡 style 객체를 통해 설정된 스타일은 CSS inline 스타일과 동일한 가중치를 가진다. 따라서 CSS를 통해 수정의 여지가 있는 스타일에는 많이 사용되지 않는다. 이 경우에는 classList를 이용한 클래스 제어가 더 효과적이다.
Attribute
메소드element.getAttribute(attributeName)
element.setAttribute(attributeName, value)
data
속성과 dataset
객체data
속성의 이름에는 콜론(:)이나 영문 대문자가 들어가서는 안된다.dataset
객체를 통해 data
속성을 가져오기 위해서는 속성 이름의 data- 뒷 부분을 사용한다(대시들은 camelCase로 변환됨)<img class="terran battle-cruiser"
src="battle-cruiser.png"
data-ship-id="324"
data-weapons="laser"
data-health="400"
data-mana="250"
data-skill="yamato-cannon"/>
<script>
console.log(target.dataset); // DOMStringMap
console.log(target.dataset.shipId); // 324
</script>
element.insertAdjacentHTML('beforebegin', text)
element.insertAdjacentHTML('afterbegin', text)
element.insertAdjacentHTML('beforeend', text)
element.insertAdjacentHTML('afterend', text)
element.firstElementChild
element.lastElementChild
element.nextElementSibling
element.previousElementSibling
node.nextSibling
node.previousSibling
element.children
element.parentElement
element.closest('selector')
: 일치하는 CSS 선택자를 찾을 때까지 자기 자신부터 시작해 위쪽으로 순회한다이벤트 객체
이벤트에서 호출되는 핸들러에는 이벤트와 관련된 모든 정보를 가지고 있는 매개변수가 전송되는데 이것이 바로 이벤트 객체다
const btnFirst = document.querySelector('.btn-first');
btnFirst.addEventListener('click', (event) => {
console.log(event);
});
이벤트 흐름
(이미지 출처 - 멋쟁이사자처럼 프론트엔드스쿨 5기 교안)
브라우저 화면에서 이벤트가 발생하면 브라우저는 가장 먼저 이벤트 대상을 찾기 시작한다.
브라우저가 이벤트 대상을 찾아갈 때는 가장 상위의 window 객체부터 document, body 순으로 DOM 트리를 따라 내려간다. 이를 캡처링 단계라고 한다. 이때 이벤트 대상을 찾아가는 과정에서 브라우저는 중간에 만나는 모든 캡처링 이벤트 리스너를 실행시킨다.
이벤트 대상을 찾고 캡처링이 끝나면 이제 다시 DOM 트리를 따라 올라가며 만나는 모든 버블링 이벤트 리스너를 실행한다. 이를 버블링 단계라고 한다.
그리고 이러한 과정에서 이벤트 리스너가 차례로 실행되는 것을 이벤트 전파(event propagation)라고 한다.
이벤트 위임
target
속성에는 이벤트가 발생한 진원지의 정보가 담겨 있다. target
속성을 통해 이벤트 리스너가 없는 요소의 이벤트가 발생했을 때도 해당 요소에 접근 할 수 있다.
currentTarget
속성에는 이벤트 리스너가 연결된 요소가 참조되어 있다.
<article class="parent">
<ol>
<li><button class="btn-first" type="button">버튼1</button></li>
<li><button type="button">버튼2</button></li>
<li><button type="button">버튼3</button></li>
</ol>
</article>
<script>
const parent = document.querySelector('.parent');
parent.addEventListener('click', function (event) {
console.log(event.target);
console.log(event.currentTarget);
if (event.target.nodeName === "BUTTON") {
event.target.innerText = "버튼4";
}
});
</script>
=> 이벤트 리스너가 없어도 마치 리스너가 있는 것처럼 사용할 수 있다. 이벤트 하나만으로도 자식 요소들을 이벤트 처리할 수 있다.