일반적으로 개발자는 DOM으로 작업을 수행해야 할 때 jQuery를 사용합니다. 그러나 거의 모든 DOM 조작은 다음에서 수행할 수 있습니다. 순수 자바스크립트 DOM API를 사용합니다.

이 API를 더 자세히 살펴보겠습니다.

마지막에는 모든 프로젝트에서 사용할 수 있는 간단한 DOM 라이브러리를 작성하게 됩니다.

DOM 쿼리

DOM 쿼리는 임의의 CSS 선택기를 인수로 사용하는 .querySelector() 메서드를 사용하여 만들어집니다.

Const myElement = document.querySelector("#foo > div.bar")

첫 번째 일치하는 요소를 반환합니다. 반대로 할 수 있습니다 - 요소가 선택자와 일치하는지 확인하십시오.

MyElement.matches("div.bar") === 참

선택자와 일치하는 모든 요소를 ​​가져오려면 다음 구문을 사용하세요.

Const myElements = document.querySelectorAll(".bar")

참조할 상위 요소를 알고 있는 경우 전체 코드를 검색하는 대신 하위 요소를 간단히 검색할 수 있습니다.

Const myChildElemet = myElement.querySelector("input") // 대신: // document.querySelector("#foo > div.bar input")

질문이 발생합니다. 그러면 .getElementsByTagName()과 같은 덜 편리한 다른 메서드를 사용하는 이유는 무엇입니까? 작은 문제가 있습니다. output.querySelector()의 결과가 업데이트되지 않고 추가할 때 새로운 요소(참조), 변경되지 않습니다.

const elements1 = document.querySelectorAll("div") const elements2 = document.getElementsByTagName("div") const newElement = document.createElement("div") document.body.appendChild(newElement) elements1.length === elements2.length // 거짓

또한 querySelectorAll()은 모든 것을 하나의 목록으로 수집하므로 매우 효율적이지 않습니다.

목록으로 작업하는 방법?

그 위에 .querySelectorAll()에는 두 가지 작은 단점이 있습니다. 결과에 대해 메서드를 호출하고 각각에 적용되기를 기대할 수는 없습니다(jQuery를 사용하는 데 익숙할 수 있음). 어쨌든 루프의 모든 요소를 ​​반복해야 합니다. 둘째, 반환된 개체는 배열이 아니라 요소 목록입니다. 따라서 배열 메서드는 작동하지 않습니다. 물론 .forEach() 와 같은 목록에 대한 메서드가 있지만 모든 경우에 적합하지는 않습니다. 따라서 목록을 배열로 변환하는 것이 좋습니다.

// Array.from() 사용 Array.from(myElements).forEach(doSomethingWithEachElement) // 또는 배열 프로토타입(ES6 이전) Array.prototype.forEach.call(myElements, doSomethingWithEachElement) // 더 쉽게: .forEach.call (myElements, doSomethingWithEachElement)

각 요소에는 "패밀리"를 참조하는 몇 가지 속성이 있습니다.

MyElement.children myElement.firstElementChild myElement.lastElementChild myElement.previousElementSibling myElement.nextElementSibling

Element 인터페이스는 Node 인터페이스에서 상속되기 때문에 다음 속성도 있습니다.

MyElement.childNodes myElement.firstChild myElement.lastChild myElement.previousSibling myElement.nextSibling myElement.parentNode myElement.parentElement

전자의 속성은 요소를 참조하는 반면 후자(.parentElement 제외)는 모든 유형의 요소 목록이 될 수 있습니다. 따라서 요소 유형을 확인할 수 있습니다.

MyElement.firstChild.nodeType === 3 // 이 요소는 텍스트 노드가 됩니다.

클래스 및 속성 추가

새 클래스를 추가하는 것은 매우 쉽습니다.

myElement.classList.add("foo") myElement.classList.remove("bar") myElement.classList.toggle("baz")

요소에 속성을 추가하는 것은 객체에 속성을 추가하는 것과 정확히 동일합니다.

// 속성 값 가져오기 const value = myElement.value // 속성을 요소 속성으로 설정 myElement.value = "(!LANG:foo" // Для установки нескольких свойств используйте.Object.assign() Object.assign(myElement, { value: "foo", id: "bar" }) // Удаление атрибута myElement.value = null !}

.getAttibute() , .setAttribute() 및 .removeAttribute() 메서드를 사용할 수 있습니다. 그들은 즉시 요소의 HTML 속성(DOM 속성과 반대)을 변경하여 브라우저를 다시 렌더링합니다(브라우저에서 개발자 도구를 사용하여 요소를 검사하여 변경 사항을 볼 수 있음). 이러한 다시 그리기에는 DOM 속성을 설정하는 것보다 더 많은 리소스가 필요할 뿐만 아니라 예기치 않은 오류가 발생할 수도 있습니다.

일반적으로 colspan 과 같이 해당 DOM 속성이 없는 요소에 사용됩니다. 또는 HTML 속성을 상속할 때와 같이 사용이 실제로 필요한 경우(참조).

CSS 스타일 추가

다른 속성과 동일한 방식으로 추가됩니다.

MyElement.style.marginLeft = "2em"

약간 특정 속성.style 을 사용하여 설정할 수 있지만 일부 계산 후에 값을 얻으려면 window.getComputedStyle() 을 사용하는 것이 좋습니다. 이 메서드는 요소를 가져와 요소 자체와 부모 요소의 스타일을 모두 포함하는 CSSStyleDeclaration을 반환합니다.

Window.getComputedStyle(myElement).getPropertyValue("왼쪽 여백")

DOM 변경

요소를 이동할 수 있습니다.

// element1을 element2의 마지막 자식으로 추가 element1.appendChild(element2) // element1의 자식으로 element2를 element3 이전에 삽입 element1.insertBefore(element2, element3)

이동하고 싶지 않지만 사본을 붙여넣으려면 다음을 사용하십시오.

// 클론 생성 const myElementClone = myElement.cloneNode() myParentElement.appendChild(myElementClone)

.cloneNode() 메서드는 부울 값을 인수로 사용하고 true이면 복제 및 자식 요소.

물론 새 요소를 만들 수 있습니다.

const myNewElement = document.createElement("div") const myNewTextNode = document.createTextNode("일부 텍스트")

그리고 위의 그림과 같이 삽입합니다. 요소를 직접 삭제할 수는 없지만 상위 요소를 통해 삭제할 수 있습니다.

MyParentElement.removeChild(myElement)

간접적으로 참조할 수도 있습니다.

MyElement.parentNode.removeChild(myElement)

요소에 대한 메서드

각 요소에는 .innerHTML 및 .textContent 와 같은 속성이 있으며 여기에는 HTML 코드와 그에 따른 텍스트 자체가 포함됩니다. 다음 예에서는 요소의 내용을 변경합니다.

// HTML 변경 myElement.innerHTML = `

새로운 콘텐츠

삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐삐

` // 이렇게 하면 내용이 제거됩니다. myElement.innerHTML = null // HTML에 추가 myElement.innerHTML += ` 계속 읽기...

사실, HTML을 변경하는 것은 나쁜 생각입니다. 왜냐하면 이전에 작성된 모든 변경 사항이 손실되고 이벤트 핸들러도 오버로드되기 때문입니다. 이 방법은 모든 HTML을 완전히 버리고 서버의 사본으로 교체하는 방식으로만 사용하는 것이 좋습니다. 이와 같이:

const link = document.createElement("a") const text = document.createTextNode("계속 읽기...") const hr = document.createElement("hr") link.href = "foo.html" link.appendChild( 텍스트) myElement.appendChild(링크) myElement.appendChild(hr)

그러나 이렇게 하면 두 개의 브라우저 다시 그리기가 발생하는 반면 .innerHTML은 하나만 발생합니다. 먼저 DocumentFragment 에 모든 것을 추가한 다음 필요한 조각을 추가하면 이 문제를 해결할 수 있습니다.

Const 조각 = document.createDocumentFragment() fragment.appendChild(text) fragment.appendChild(hr) myElement.appendChild(fragment)

이벤트 핸들러

가장 간단한 핸들러 중 하나:

MyElement.onclick = 기능 onclick (event) ( console.log(event.type + " 해고됨 ") )

그러나 일반적으로 피해야 합니다. 여기에서 .onclick은 요소의 속성이며 이론상 변경할 수 있지만 이전 함수를 참조하는 또 다른 함수를 사용하여 다른 핸들러를 추가할 수 없습니다.

핸들러를 추가하려면 .addEventListener()를 사용하는 것이 좋습니다. 이벤트 유형, 실행될 때마다 호출되는 함수, 구성 개체(나중에 설명함)의 세 가지 인수가 필요합니다.

MyElement.addEventListener("클릭", 함수(이벤트) ( console.log(event.type + " 해고됨") )) myElement.addEventListener("클릭", 함수(이벤트) ( console.log(event.type + " 다시 해고당했습니다") ))

event.target 속성은 이벤트가 연결된 요소를 나타냅니다.

따라서 모든 속성에 액세스할 수 있습니다.

// `forms` 속성은 모든 양식에 대한 링크를 포함하는 배열입니다. const myForm = document.forms const myInputElements = myForm.querySelectorAll("input") Array.from(myInputElements).forEach(el => ( el.addEventListener(" 변경 ", 기능(이벤트) ( console.log(event.target.value) )) ))

기본 작업 방지

이를 위해 표준 작업을 차단하는 .preventDefault() 메서드가 사용됩니다. 예를 들어 클라이언트 측 승인이 성공하지 못한 경우 양식 제출을 차단합니다.

MyForm.addEventListener("제출", 함수(이벤트) ( const name = this.querySelector("#name") if (name.value === "(!LANG:Donald Duck") { alert("You gotta be kidding!") event.preventDefault() } }) !}

.stopPropagation() 메서드는 자식에 연결된 특정 이벤트 핸들러와 부모에 연결된 동일한 이벤트에 대한 두 번째 핸들러가 있는 경우 도움이 됩니다.

앞서 언급했듯이 .addEventListener() 메서드는 선택적 세 번째 인수를 구성 객체로 사용합니다. 이 객체는 다음 부울 속성 중 하나를 포함해야 합니다(기본적으로 모두 false로 설정됨).

  • 캡처: 이벤트는 DOM 아래의 다른 요소보다 먼저 이 요소에 첨부됩니다.
  • 한 번: 이벤트를 한 번만 고정할 수 있습니다.
  • 수동: event.preventDefault()는 무시됩니다(오류 중 예외).

가장 일반적인 속성은 .capture 이며 너무 일반적이어서 이에 대한 약칭이 있습니다. config 개체에 전달하는 대신 여기에 값을 지정하기만 하면 됩니다.

MyElement.addEventListener(유형, 수신기, true)

핸들러는 .removeEventListener() 메서드를 사용하여 제거됩니다. 이 메서드는 이벤트 유형과 제거할 핸들러에 대한 참조라는 두 가지 인수를 사용합니다. 예를 들어, Once 속성은 다음과 같이 구현할 수 있습니다.

MyElement.addEventListener("change", function listener (event) ( console.log(event.type + " got trigger on " + this) this.removeEventListener("change", listener) ))

계승

요소가 있고 모든 하위 요소에 대한 이벤트 핸들러를 추가하려는 경우를 가정해 보겠습니다. 그런 다음 위에 표시된 대로 myForm.querySelectorAll("input") 메서드를 사용하여 반복해야 합니다. 그러나 단순히 양식에 요소를 추가하고 event.target을 사용하여 해당 내용을 확인할 수 있습니다.

MyForm.addEventListener("변경", 함수(이벤트) ( const target = event.target if (target.matches("input")) ( console.log(target.value) ) ))

그리고 이 방법의 또 다른 장점은 핸들러가 새 자식 요소에 자동으로 첨부된다는 것입니다.

생기

애니메이션을 추가하는 가장 쉬운 방법은 CSS를 transition 속성과 함께 사용하는 것입니다. 그러나 더 많은 유연성(예: 게임)을 위해서는 JavaScript가 더 적합합니다.

애니메이션이 끝날 때까지 window.setTimeout() 메서드를 호출하는 것은 좋은 생각이 아닙니다. 특히 모바일 장치에서 애플리케이션이 멈출 수 있기 때문입니다. 다음 다시 그릴 때까지 모든 변경 사항을 저장하려면 window.requestAnimationFrame()을 사용하는 것이 좋습니다. 함수를 인수로 사용하여 차례로 타임스탬프를 수신합니다.

const 시작 = window.performance.now() const 지속 시간 = 2000 window.requestAnimationFrame(function fadeIn (지금)) ( const 진행 = 지금 - 시작 myElement.style.opacity = 진행 / 지속 시간 if (진행)< duration) { window.requestAnimationFrame(fadeIn) } }

이러한 방식으로 매우 부드러운 애니메이션이 달성됩니다. Mark Brown은 그의 기사에서 이 주제에 대해 설명합니다.

우리만의 라이브러리 쓰기

DOM에서 요소를 사용하여 작업을 수행하기 위해 항상 요소를 반복해야 한다는 사실은 jQuery의 $(".foo").css((color: "red")) 구문에 비해 상당히 지루해 보일 수 있습니다. 그러나 이 작업을 더 쉽게 하기 위해 자신만의 방법을 작성해 보는 것은 어떻습니까?

Const $ = function $(selector, context = document) ( const elements = Array.from(context.querySelectorAll(selector)) return ( elements, html (newHtml) ( this.elements.forEach(element => ( element.innerHTML = newHtml )) return this ), css (newCss) ( this.elements.forEach(element => ( Object.assign(element.style, newCss) )) return this ), on (event, handler, options) ( this.elements .forEach(element => ( element.addEventListener(event, handler, options) )) return this ) ) )

의사 코드

$(".rightArrow").click(function() ( rightArrowParents = this.dom(); //.dom();은 의사 함수입니다... 전체 alert(rightArrowParents); ));

알람 메시지는 다음과 같습니다.

바디 div.lol a.rightArrow

javascript/jquery로 이것을 어떻게 얻을 수 있습니까?

다음과 같이 jQuery 사용(이벤트를 제외하고 jQuery를 사용하지 않는 솔루션, 중요한 경우 함수 호출이 훨씬 적음):

실시간 예:

$(".rightArrow").click(function() ( var rightArrowParents = ; $(this).parents().addBack().not("html").each(function() ( var 항목 = this.tagName .toLowerCase(); if (this.className) ( 항목 += "." + this.className.replace(/ /g, "."); ) rightArrowParents.push(entry); )), 경고(rightArrowParents.join (" ")), 거짓 반환; ));

여기를 클릭

(라이브 예제에서 여러 클래스를 처리하는 방법을 보여주기 위해 div의 class 속성을 lol multi로 업데이트했습니다.)

다음은 정확한 요소 일치를 위한 솔루션입니다.

선택자는 다음을 이해하는 것이 중요합니다. (현실이 아니다) 크롬 도구가 표시하는 DOM의 요소를 고유하게 식별하지 않습니다. ( 예를 들어, 연속적인 span 요소 목록을 구별하지 않습니다. 포지셔닝/인덱싱 정보 없음)

$.fn.fullSelector = function () ( var path = this.parents().addBack(); var quickCss = path.get().map(function (item) ( var self = $(item), id = item .id ? "#" + item.id: "", clss = item.classList.length ? item.classList.toString().split(" ").map(function (c) ( return "." + c; )).join("") : "", 이름 = item.nodeName.toLowerCase(), 인덱스 = self.siblings(name).length ? ":nth-child(" + (self.index() + 1) + ")" : ""; if (name === "html" || name === "body") ( return name; ) return name + index + id + clss; )).join(" > ") ; 빠른 CSS를 반환; );

그리고 다음과 같이 사용할 수 있습니다.

Console.log($("일부 선택기").fullSelector());

T.J에서 스니펫을 옮겼습니다. 작은 jQuery 플러그인에 대한 크라우더. 나는 jQuery 버전을 사용했는데, 그가 옳다고 해도 완전히 불필요한 오버헤드이지만 디버깅 목적으로만 사용하므로 상관하지 않습니다.

용법:

중첩 범위
단순 범위
사전

// 결과(배열): ["body", "div.sampleClass"] $("span").getDomPath(false) // 결과(문자열): body > div.sampleClass $("span").getDomPath( ) // 결과(배열): ["body", "div#test"] $("pre").getDomPath(false) // 결과(string): body > div#test $("pre").getDomPath ()

var obj = $("# 편집 버튼 표시"), 경로 = ""; while (typeof obj.prop("tagName") != "undefined")( if (obj.attr("class"))( path = "."+obj.attr("class").replace(/\s /g , ".") + 경로; ) if (obj.attr("id"))( 경로 = "#"+obj.attr("id") + 경로; ) 경로 = " " +obj.prop( "태그 이름").toLowerCase() + 경로; obj = obj.parent(); ) console.log(경로);

안녕하세요 이 함수는 경로에 나타나지 않는 현재 요소와 관련된 오류를 해결합니다.

지금 확인하세요

$j(".wrapper").click(function(event) ( selectedElement=$j(event.target); var rightArrowParents = ; $j(event.target).parents().not("html,body") .each(function() ( var 항목 = this.tagName.toLowerCase(); if (this.className) ( 항목 += "." + this.className.replace(/ /g, "."); )else if (this.id)( 항목 += "#" + this.id; ) 항목=replaceAll(항목,"..","."), rightArrowParents.push(항목); )), rightArrowParents.reverse(); //if(event.target.nodeName.toLowerCase()=="a" || event.target.nodeName.toLowerCase()=="h1")( var 항목 = event.target.nodeName.toLowerCase(); if (event.target.className) ( 항목 += "." + event.target.className.replace(/ /g, "."); )else if(event.target.id)( 항목 += "#" + event.target.id; ) rightArrowParents.push(entry); // )

여기서 $j = jQuery 변수

또한 클래스 이름에서 .. 문제를 해결하십시오.

다음은 바꾸기 기능입니다.

함수 escapeRegExp(str) ( return str.replace(/([.*+?^=!:$()()|\[\]\/\\])/g, "\\$1"); ) 함수 replaceAll(str, 찾기, 바꾸기) ( return str.replace(new RegExp(escapeRegExp(찾기), "g"), 바꾸기); )

다음은 jQuery 경로를 반환하는 기본 JS 버전입니다. 또한 요소에 대한 ID가 있으면 추가합니다. 이렇게 하면 배열에 id가 표시되는 경우 최단 경로를 선택할 수 있는 옵션이 제공됩니다.

varpath = getDomPath(요소); console.log(경로.join(" > "));

Body > section:eq(0) > div:eq(3) > section#content > section#firehose > div#firehoselist > article#firehose-46813651 > 헤더 > h2 > span#title-46813651

다음은 기능입니다.

함수 getDomPath(el) ( var 스택 = ; 동안 (el.parentNode != null) ( console.log(el.nodeName); var sibCount = 0; var sibIndex = 0; for (var i = 0, i)< el.parentNode.childNodes.length; i++) { var sib = el.parentNode.childNodes[i]; if (sib.nodeName == el.nodeName) { if (sib === el) { sibIndex = sibCount; } sibCount++; } } if (el.hasAttribute("id") && el.id != "") { stack.unshift(el.nodeName.toLowerCase() + "#" + el.id); } else if (sibCount >1) ( stack.unshift(el.nodeName.toLowerCase() + ":eq(" + sibIndex + ")"); ) else ( stack.unshift(el.nodeName.toLowerCase()); ) el = el.parentNode ; ) 반환 stack.slice(1); // html 요소 제거)

복잡하고 무거운 웹 애플리케이션이 요즘 보편화되었습니다. 다양한 기능을 갖춘 jQuery와 같은 브라우저 간 및 사용하기 쉬운 라이브러리는 즉시 DOM 조작에 큰 도움이 될 수 있습니다. 따라서 많은 개발자들이 문제가 많았던 네이티브 DOM API로 작업하는 것보다 이러한 라이브러리를 더 자주 사용하는 것은 놀라운 일이 아닙니다. 그리고 브라우저의 차이가 여전히 문제지만, DOM은 jQuery가 인기를 얻었던 5-6년 전보다 지금 더 나은 모양입니다.

이 글에서 나는 부모, 자식, 이웃 관계에 초점을 맞춰 HTML을 조작하는 DOM의 능력을 보여줄 것이다. 이러한 기능에 대한 브라우저 지원 분석으로 결론을 내리겠지만 기본 기능 구현의 버그와 불일치로 인해 jQuery 유형 라이브러리가 여전히 좋은 옵션이라는 점을 명심하십시오.

자식 노드 계산

데모를 위해 다음 HTML 마크업을 사용할 것이며 이 문서 전체에서 여러 번 변경할 것입니다.

  • 예 1
  • 예 2
  • 예 3
  • 예 4
  • 예 5
  • 예 6

변수 myList = document.getElementById("myList"); console.log(myList.children.length); // 6 console.log(myList.childElementCount); // 6

보시다시피 사용된 기술은 다르지만 결과는 동일합니다. 첫 번째 경우에는 children 속성을 사용합니다. 이것은 읽기 전용 속성이며 컬렉션을 반환합니다. HTML 요소, 요청된 요소 내부에 위치합니다. 숫자를 계산하기 위해 이 컬렉션의 length 속성을 사용합니다.

두 번째 예에서는 더 깔끔하고 잠재적으로 유지 관리가 더 쉬운 방법인 childElementCount 메서드를 사용하고 있습니다(나중에 자세히 설명하면 이 메서드가 수행하는 작업을 이해하는 데 문제가 없을 것이라고 생각합니다).

(children.length 대신) childNodes.length를 사용하려고 시도할 수 있지만 결과를 보십시오.

변수 myList = document.getElementById("myList"); console.log(myList.childNodes.length); // 13

childNodes는 공백을 포함한 모든 노드의 모음이기 때문에 13을 반환합니다. 자식 노드와 자식 요소 노드의 차이에 관심이 있다면 이 점을 염두에 두십시오.

자식 노드의 존재 확인

요소에 자식 노드가 있는지 확인하려면 hasChildNodes() 메서드를 사용할 수 있습니다. 메서드 반환 부울존재 또는 부재 표시:

변수 myList = document.getElementById("myList"); console.log(myList.hasChildNodes()); // 진실

내 목록에 자식 노드가 있다는 것을 알고 있지만 HTML을 변경할 수 있습니다. 이제 마크업은 다음과 같습니다.

다음은 hasChildNodes()를 다시 실행한 결과입니다.

Console.log(myList.hasChildNodes()); // 진실

메서드는 여전히 true 를 반환합니다. 목록에는 요소가 포함되어 있지 않지만 유효한 노드 유형인 공백이 포함되어 있습니다. 이 방법요소 노드뿐만 아니라 모든 노드를 고려합니다. hasChildNodes()가 false를 반환하려면 마크업을 다시 변경해야 합니다.

이제 예상 결과가 콘솔에 표시됩니다.

Console.log(myList.hasChildNodes()); // 거짓

물론 공백이 발생할 수 있다는 것을 알고 있으면 먼저 자식 노드가 있는지 확인한 다음 nodeType 속성을 사용하여 그 사이에 요소 노드가 있는지 확인합니다.

자식 요소 추가 및 제거

DOM에서 요소를 추가하고 제거하는 데 사용할 수 있는 기술이 있습니다. 이들 중 가장 유명한 것은 createElement() 및 appendChild() 메소드의 조합을 기반으로 합니다.

VarmyEl = document.createElement("div"); document.body.appendChild(myEl);

이 경우 내가 만들고 있는

createElement() 메서드를 사용한 다음 body에 추가합니다. 매우 간단하며 이전에 이 기술을 사용한 적이 있을 것입니다.

그러나 특별히 제작된 요소를 삽입하는 대신 appendChild()를 사용하여 기존 요소를 간단히 이동할 수도 있습니다. 다음 마크업이 있다고 가정합니다.

  • 예 1
  • 예 2
  • 예 3
  • 예 4
  • 예 5
  • 예 6

예제 텍스트

다음 코드를 사용하여 목록의 위치를 ​​변경할 수 있습니다.

Var myList = document.getElementById("myList"), 컨테이너 = document.getElementById("c"); 컨테이너.appendChild(myList);

최종 DOM은 다음과 같습니다.

예제 텍스트

  • 예 1
  • 예 2
  • 예 3
  • 예 4
  • 예 5
  • 예 6

전체 목록이 해당 위치(단락 위)에서 제거된 다음 그 뒤, 닫기 본문 앞에 삽입되었음을 유의하십시오. appendChild() 메서드는 일반적으로 createElement() 로 생성된 요소를 추가하는 데 사용되지만 기존 요소를 이동하는 데 사용할 수도 있습니다.

removeChild()를 사용하여 DOM에서 자식 요소를 완전히 제거할 수도 있습니다. 이전 예에서 목록이 제거되는 방법은 다음과 같습니다.

Var myList = document.getElementById("myList"), 컨테이너 = document.getElementById("c"); container.removeChild(myList);

이제 요소가 제거되었습니다. removeChild() 메서드는 제거된 요소를 반환하고 나중에 필요할 때를 대비하여 저장할 수 있습니다.

변수 myOldChild = document.body.removeChild(myList); document.body.appendChild(myOldChild);

비교적 최근에 사양에 추가된 ChildNode.remove() 메서드도 있습니다.

변수 myList = document.getElementById("myList"); myList.remove();

이 메서드는 원격 개체를 반환하지 않으며 IE에서 작동하지 않습니다(Edge만 해당). 그리고 두 방법 모두 요소 노드와 동일한 방식으로 텍스트 노드를 제거합니다.

자식 요소 교체

새 요소가 존재하거나 처음부터 생성했는지 여부에 관계없이 기존 자식 요소를 새 요소로 바꿀 수 있습니다. 다음은 마크업입니다.

예제 텍스트

변수 myPar = document.getElementById("par"), myDiv = document.createElement("div"); myDiv.className = "예시"; myDiv.appendChild(document.createTextNode("새 요소 텍스트")); document.body.replaceChild(myDiv, myPar);

새 요소 텍스트

보시다시피, replaceChild() 메서드는 두 개의 인수를 사용합니다. 새 요소와 대체하는 이전 요소입니다.

이 방법을 사용하여 기존 요소를 이동할 수도 있습니다. 다음 HTML을 살펴보십시오.

예제 텍스트 1

예제 텍스트 2

예제 텍스트 3

세 번째 단락을 다음 코드로 첫 번째 단락으로 바꿀 수 있습니다.

변수 myPar1 = document.getElementById("par1"), myPar3 = document.getElementById("par3"); document.body.replaceChild(myPar1, myPar3);

이제 생성된 DOM은 다음과 같습니다.

예제 텍스트 2

예제 텍스트 1

특정 하위 요소 선택

여러 가지가 있습니다 다른 방법들특정 요소를 선택합니다. 앞에서 설명한 것처럼 children 컬렉션이나 childNodes 속성을 사용하여 시작할 수 있습니다. 그러나 다른 옵션을 살펴보겠습니다.

firstElementChild 및 lastElementChild 속성은 이름에서 예상한 대로 정확히 수행합니다. 첫 번째 및 마지막 자식 요소를 선택합니다. 마크업으로 돌아가 보겠습니다.

  • 예 1
  • 예 2
  • 예 3
  • 예 4
  • 예 5
  • 예 6

다음 속성을 사용하여 첫 번째 요소와 마지막 요소를 선택할 수 있습니다.

변수 myList = document.getElementById("myList"); console.log(myList.firstElementChild.innerHTML); // "예제 1" console.log(myList.lastElementChild.innerHTML); // "예시 6"

첫 번째 또는 마지막이 아닌 다른 자식 요소를 선택하려는 경우에는 previousElementSibling 및 nextElementSibling 속성을 사용할 수도 있습니다. 이것은 firstElementChild 및 lastElementChild 속성을 결합하여 수행됩니다.

변수 myList = document.getElementById("myList"); console.log(myList.firstElementChild.nextElementSibling.innerHTML); // "예시 2" console.log(myList.lastElementChild.previousElementSibling.innerHTML); // "예제 5"

유사한 속성인 firstChild , lastChild , previousSibling 및 nextSibling 도 있지만 요소뿐만 아니라 모든 노드 유형을 고려합니다. 일반적으로 요소 노드만 고려하는 속성은 모든 노드를 선택하는 속성보다 유용합니다.

DOM에 콘텐츠 삽입

이미 DOM에 요소를 삽입하는 방법을 살펴보았습니다. 유사한 주제로 이동하여 콘텐츠 삽입을 위한 새로운 기능을 살펴보겠습니다.

먼저, replaceChild() 와 매우 유사한 간단한 insertBefore() 메서드가 있습니다. 두 개의 인수를 사용하고 기존 요소뿐 아니라 새 요소에서도 작동합니다. 다음은 마크업입니다.

  • 예 1
  • 예 2
  • 예 3
  • 예 4
  • 예 5
  • 예 6

예시 단락

단락을 주목하세요. 먼저 제거한 다음 목록 앞에 삽입하겠습니다.

Var myList = document.getElementById("myList"), 컨테이너 = document.getElementBy("c"), myPar = document.getElementById("par"); container.insertBefore(myPar, myList);

결과 HTML에서 단락이 목록 앞에 올 것이며 이는 요소를 래핑하는 또 다른 방법입니다.

예시 단락

  • 예 1
  • 예 2
  • 예 3
  • 예 4
  • 예 5
  • 예 6

replaceChild() 와 마찬가지로 insertBefore() 는 추가할 요소와 삽입하려는 요소 앞에 두 개의 인수를 사용합니다.

이 방법은 간단합니다. 이제 더 강력한 삽입 방법인 insertAdjacentHTML() 메서드를 사용해 보겠습니다.