이 글은 인터넷 강의를 기반으로 간단하게 정리한 글입니다.
설명이 다소 간단할 수 있습니다.
live
document.getElementsByTagName()
등은 은HTMLCollection 오브젝트
를 반환하여
이 오브젝트에 엘리먼트를 추가/삭제 하면즉시 반영된다.
static
document.querySelector()
혹은document.querySelectorAll()
은NodeList 오브젝트
를 반환한다.
이 오브젝트에 엘리먼트를 추가/삭제하면반영되지 않는다.
다시 NodeList 오브젝트를 불러와야한다.childNodes 프로퍼티가 반환하는 NodeList 객체는 live 임을 주의하자.
단 속성은
HTMLCollection 오브젝트
이던NodeList 오브젝트
이던 즉시 반영된다.el.onclick = (event) => { el.classList.add("piano"); };
상태 변경과 상관없이 안전하게 DOM 컬렉션을 사용하려면 HTMLCollection 이나 NodeList 객체를
배열로 변경하여 사용하는 것을 권장한다.
이벤트 핸들러는 onclick 프로퍼티의 값으로 할당되기 때문에
한 이벤트만 동작한다.el.onclick = function() {}
이벤트 리스너는 이벤트를 배열로 관리하기 때문에 다중으로 할당할 수 있다.
즉 해당 이벤트가 발생하면 배열에 있는 모든 리스너 들이 동작한다.el.addEventListener(event, function, useCapture);
웹 API에서 객체 인터페이스의 속성을 나타낸다.
이 속성들은 JavaScript 코드에서 사용될 수 있다.
즉, IDL 속성은 웹 표준에서 정의된 웹 API를
JavaScript에서 사용할 수 있게 연결해주는 역할을 한다.예를 들어, HTML 요소를 나타내는 HTMLElement 인터페이스에는
className, innerHTML 등의 IDL 속성이 있고,
이를 통해 해당 HTML 요소의 클래스 이름이나 내부 HTML을 가져오거나 설정할 수 있다.
IDL 속성은 주로 소문자로 시작하는 주로 camelCase 형태로 작성되며,
(spellcheck 등 은 모두 소문자)
대응하는 HTML 속성이 있는 경우에는 해당 HTML 속성과 값을 공유한다.
HTML 속성과 IDL 속성은 서로 연동되어 있지만, 항상 같은 값을 가지는 것은 아니다.예를 들어, input 요소의 value IDL 속성은 사용자가 입력한 값을 반영하지만,
value HTML 속성은 원래의 초기값을 유지한다.
또한 타입도 일치하지 않는 경우도 있다.
<p id=five tabeindex="10">String, Number 타입</p>
const five = docmunet.getElementById("five"); console.log(typeof five.getAttribute("tabindex")); // string, HTML 속성 console.log(typeof five.tabIndex); // number, IDL 속성
<div id=music name="클래식" checked>음악</div>
const music = document.getElementById("music"); console.log(music.name); // undefined console.log(music.checked); // undefined
유효한지 안한지는 https://html.spec.whatwg.org/#toc-semantics 에서 확인할 수 있다.
카멜케이스
el.style.fontSize
속성명 그대로 사용
el.style["font-size"]
<input type=checkbox id=good checked>
<label id=nice for=good>굿 </label>
const nice = document.getElementById("nice");
console.log(nice.for); // undefined
console.log(nice.htmlFor); // good
모든 대문자는 소문자로 변경되어서 NamdeNodeMap 오브젝트에 설정된다.
<p id="p_id" testCode="hello">asdf</p>
hasAttribute 의 파라미터도 모두 소문자로 변경된다.console.log(el.hasAttribute("none"))); // false console.log(el.hasAttribute("testCode"))); // true console.log(el.hasAttribute("testcode"))); // true console.log(el.hasAttribute("TESTCODE"))); // true console.log(el.attributes.testcode.nodeValue); // hello
단 SVG 엘리먼트에서는 대소문자를 구분한다.
HTML에 작성된 속성만을 대상으로 참조한다.
자바스크립트로 추가한 속성은 참조하지 못한다.속성이 없으면 null을 반환한다.
따라서 속성 값으로 null 을 사용하는 것은 지양하는 것이 좋다.
글로벌 속성도 마찬가지이다.
el.getAttribute("title") 시 null을 반환한다.단 DOM3 환경일 경우 빈문자열을 반환한다.
안전성을 보장 하기위해서 hasAttribute()로 속성의 존재 여부를 체크하는 것이 좋다.
<svg width=300 height=60>
<text id=same y=20 textLength=50%>50% 간격</text>
<text y=50 textLength=100%>100% 간격</text>
</svg>
const same = document.getElementById("same");
typeof same.textLength; // Object
HTML의 SVG에 새로운 속성을 만들때 setAttributeNodeNS() 로 속성을 설정할 수 없다.
setAttribute()로 해야된다.<svg width=300 height=60> <text id=same y=20 textLength=50%>50% 간격</text> <text y=50 textLength=100%>100% 간격</text> </svg>
document.getElementById("five").setAttribute("textLength", "100%");
setAttributeNodeNS() 는 XML 용이라고 생각하자.
반드시 프로퍼티로 확인해야한다.
getAttribute() 나 element.attributes.getNamedItem().value로 확인하면
변경되기 이전 값이 반환된다.따라서 속성값을 변경할때는 setAttribute()를 사용하자. live로 적용된다.
이 둘을 사용하면 HTML 스펙에 정의되지 않은 Custom 속성을 사용할 수 있다.
속성이 없으면 속성을 추가하고 true를 반환한다.
속성이 있으면 속성을 삭제하고 false를 반환한다.반환 타입은 추가/삭제 이후의 속성 유무 값으로 생각하면 될 것 같다.
두번째 파라미터에 true(추가)/false(삭제) 를 지정하면 토글이 아니라
이 상태 값으로 지정한다.
자동으로 생성하기 때문이다.
querySelector가 더 느리다.
하지만 좀더 세부적인 조건을 걸 수 있고 일관된 방식으로 요소를 취즉할 수 있다.
id 어트리뷰트가 있는경우 getElementById 메서드를 사용하고
없는 경우 querySelector*** 사용을 권장한다.
innerText는 css에 순종적이여서 visibility: hidden 같이
비표시로 지정된 요소 노드의 텍스트는 반환하지 않는다.
그리고 css를 고려해야하기 때문에 textContent보다 느리다.
HTML 새니티제이션은 사용자로부터 입력받은 데이터에 의해 발생할 수 있는
크로스 사이트 스크립팅 공격을 예방하기 위재 잠재적 위험을 제거하는 기능DomPurify 라이브러리를 사용하는 것을 권장한다.
XSS 예시
document.getElementById("wrapper2").innerHTML = `<p>클릭</p>`;
event.preventDefault()
를 사용하면 확인 다이어로그 팝업창이 표시된다고하나
크롬 107 버전에서는 표시되지 않는다.
따라서 아래와 같이 사용하면 된다.
window.alert()
window.confirm()
window.prompt()
를 콜백함수에 사용하면
에러가 난다.const before = (event) => { event.preventDefault(); return event.returnValue = "확인 창 표시"; }; window.addEventListener("beforeunload", before, true);