DOM 조작 기술: 부모, 자식 및 이웃 요소. 순수 JavaScript DOM 조작 DOM에 콘텐츠 삽입

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

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

자식 노드 계산

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

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

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

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

두 번째 예에서는 childElementCount 메서드를 사용하고 있습니다. 이 메서드는 더 깔끔하고 잠재적으로 유지 관리가 더 쉬운 방법입니다.

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

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

childNodes는 공백을 포함한 모든 노드의 모음이기 때문에 13을 반환합니다. 자식 노드와 자식 요소 노드의 차이에 관심이 있는 경우 이 점을 명심하세요.

하위 노드의 존재 확인

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

Var 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() 메서드는 제거된 요소를 반환하며 나중에 필요할 경우를 대비하여 저장할 수 있습니다.

Var myOldChild = document.body.removeChild(myList); document.body.appendChild(myOldChild);

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

Var myList = document.getElementById("myList"); myList.remove();

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

하위 요소 교체

새 요소가 존재하든 처음부터 새로 생성하든 관계없이 기존 자식 요소를 새 요소로 바꿀 수 있습니다. 마크업은 다음과 같습니다.

예제 텍스트

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

새 요소 텍스트

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

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

예제 텍스트 1

예제 텍스트 2

예제 텍스트 3

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

Var 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

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

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

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

Var 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() 메서드를 사용해 봅시다.

일반적으로 개발자는 DOM으로 작업을 수행해야 할 때 jQuery를 사용합니다. 그러나 DOM API를 사용하여 순수한 JavaScript에서 거의 모든 DOM 조작을 수행할 수 있습니다.

이 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() )를 사용합니까? 작은 문제가 있습니다. .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("바") myElement.classList.toggle("baz")

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

// 속성 값 가져오기 const value = myElement.value // 속성을 요소의 속성으로 설정 myElement.value = "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) // element3 앞에 element1의 자식으로 element2를 삽입 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 = ` 새 콘텐츠 ( el.addEventListener("change", function (event) ( console.log(event.target.value) )) ))

기본 조치 방지

이를 위해 표준 작업을 차단하는 .preventDefault() 메서드가 사용됩니다. 예를 들어 클라이언트 측 승인에 실패하면 양식 제출을 차단합니다.

MyForm.addEventListener("제출", function(event) ( const name = this.querySelector("#name") if (name.value === "Donald Duck)") { alert("You gotta be kidding!") event.preventDefault() } }) !}

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

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

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

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

MyElement.addEventListener(유형, 리스너, 참)

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

MyElement.addEventListener("변경", 함수 리스너(이벤트) ( console.log(event.type + "에서 트리거됨 " + this) this.removeEventListener("변경", 리스너) ))

계승

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

MyForm.addEventListener("변경", function(event) ( const target = event.target if (target.matches("input")) ( console.log(target.value) ) ))

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

생기

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

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

const start = window.performance.now() const duration = 2000 window.requestAnimationFrame(function fadeIn (now)) ( const 진행 = 지금 - 시작 myElement.style.opacity = 진행 / 기간 if (progress< 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 entry = this.tagName .toLowerCase(); if (this.className) ( entry += "." + this.className.replace(/ /g, "."); ) rightArrowParents.push(entry); )); alert(rightArrowParents.join (" ")); 거짓 반환; )); 여기를 클릭

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

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

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

$.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("") : "", name = item.nodeName.toLowerCase(), index = self.siblings(name).length ? ":nth-child(" + (self.index() + 1) + ")" : ""; if (name === "html" || name === "body") ( return name; ) return name + index + id + clss; )).join(" > ") ; quickCss를 반환합니다. );

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

Console.log($("some-selector").fullSelector());

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

용법:

중첩된 스팬 단순 스팬 사전

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

var obj = $("#show-editor-button"), 경로 = ""; while (typeof obj.prop("tagName") != "정의되지 않음")( if (obj.attr("class"))( path = "."+obj.attr("class").replace(/\s /g , ".") + 경로; ) if (obj.attr("id"))( 경로 = "#"+obj.attr("id") + 경로; ) 경로 = " " +obj.prop( "tagName").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 entry = this.tagName.toLowerCase(); if (this.className) ( entry += "." + this.className.replace(/ /g, "."); )else if (this.id)( entry += "#" + this.id; ) entry=replaceAll(entry,"..","."); rightArrowParents.push(entry); )); rightArrowParents.reverse(); //if(event.target.nodeName.toLowerCase()=="a" || event.target.nodeName.toLowerCase()=="h1")( var entry = event.target.nodeName.toLowerCase(); if (event.target.className) ( entry += "." + event.target.className.replace(/ /g, "."); )else if(event.target.id)( entry += "#" + event.target.id; ) rightArrowParents.push(entry); // )

여기서 $j = jQuery 변수

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

교체 기능은 다음과 같습니다.

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

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

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

본문 > section:eq(0) > div:eq(3) > section#content > section#firehose > div#firehoselist > article#firehose-46813651 > header > h2 > span#title-46813651

여기에 기능이 있습니다.

함수 getDomPath(el) ( var stack = ; while (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 ; ) return stack.slice(1); // html 요소 제거 )



질문이 있으신가요?

오타 신고

편집자에게 보낼 텍스트: