>웹 프론트엔드 >JS 튜토리얼 >js_javascript 기술에서 가장 가까운 공통 조상 요소를 찾기 위한 구현 코드

js_javascript 기술에서 가장 가까운 공통 조상 요소를 찾기 위한 구현 코드

WBOY
WBOY원래의
2016-05-16 18:12:561357검색

먼저 개념을 살펴보겠습니다. DOM은 트리이고 루트 노드는 Document입니다.
js_javascript 기술에서 가장 가까운 공통 조상 요소를 찾기 위한 구현 코드
소위 "최근 공통 조상"으로 표현됩니다. 요소"는 주어진 일련의 요소를 참조하며, 트리에서 가장 깊이가 높지만 이러한 모든 요소의 조상이기도 한 요소를 찾습니다.

예를 들어 위 그림에서 I와 G의 결과는 C, G와 H의 결과는 A, D와 E의 결과는 html, C와 B의 결과는 html, 등.

테스트 중심
논리적인 질문의 경우 함수가 맞는지 완전히 확신할 수 없기 때문에 여전히 테스트 함수를 먼저 구성하고 함수가 테스트를 통과하도록 노력합니다.

이번에는 위 그림의 구조를 DOM 구조로 사용했는데, A는 body를, B는 head를, 다른 노드들은 div 요소를 동시에 사용합니다. 테스트의 입력 및 출력으로 사용됩니다. 먼저 테스트를 구성합니다.

코드 복사 코드는 다음과 같습니다.

function test() {
var result;
result = find('i', 'g')
result.id !== 'c' && Alert(' 실패(i, g)');
result = find('g' , 'h')
result.id !== 'a' && Alert('fail (g, h)');
result = find('d', 'e');
result.nodeName.toLowerCase() !== 'html' && Alert('fail (d, e)')
result = find('c', 'b');
result.nodeName.toLowerCase () !== 'html' && Alert('fail (c, b)')

기본 로직
이번 로직은 대략 다음과 같습니다.

1. 주어진 각 요소에 대해 상위 요소에서 문서까지 위쪽으로 이동합니다.
2. 순회 프로세스 중에 전달된 각 요소를 순서화된 맵에 저장합니다. 해당 요소는 키로, 순회 횟수는 값으로 사용됩니다.
2. 마지막으로 맵을 순회하여 첫 번째 값이 주어진 요소의 수와 동일한 항목을 찾습니다. 순회에서 모든 요소가 전달된 첫 번째 요소, 즉 가장 최근의 공통 요소입니다. 조상 요소.
세부 문제
실제 프로세스에서는 맵 구성이 더 중요합니다. 여기에는 두 가지 문제가 있습니다.

1. 맵은 요소를 키로 직접 사용할 수 없으며 다음으로 변환해야 합니다. 적절한 기본 유형(예: 숫자, 문자열, Regex 등).
2. Chrome은 개체의 키를 자동으로 정렬하므로 숫자 유형을 키로 사용하지 마세요.

첫 번째 질문의 경우 고유 식별자 역할을 할 적절한 필드를 요소에 바인딩해야 합니다. 다행스럽게도 HTML5는 DOM의 메타데이터 전달 용량을 크게 향상시키는 data-* 속성을 제공하므로 원하는 속성을 과감하게 추가할 수 있습니다.

두 번째 질문은 그 자체로는 어렵지 않습니다. 생성된 식별자에 숫자를 피하거나 밑줄을 추가하거나 String.fromCharCode를 사용하여 문자로 변환하는 것이 좋습니다. , 그것은 중요하지 않습니다.
구현 코드
저는 주로 JAVA 스타일을 선호하기 때문에 코드가 약간 깁니다. 모든 문과 모든 분기가 명확하기 때문에 조건 분기를 처리하는 데 && 또는 ||를 사용하는 것을 좋아하지 않습니다. 중괄호와 같은 경우에는 실제로 효과적인 코드가 간소화됩니다. 토글같은 플러그인 설치하기 너무 귀찮고 스크롤바도 보기 싫어서 그냥 여기에 던졌습니다.

코드 복사 코드는 다음과 같습니다.
function find() {
var length = 인수 .length,
i = 0,
node, //현재 노드
parent, //부모 노드
counter = 0,
uuid, //DOM의 고유 식별자
hash = {}; //최종 결과 맵

//각 요소에 대해 문서로 위쪽으로 이동합니다
//이 이중 레이어 루프는 불가피합니다
(; i < length; i ) {
//노드 가져오기
node = 인수[i]
if (typeof node == 'string') {
node = document.getElementById(node) ;
}
//위로 이동
while (parent = node.parentElement || node.parentNode) {
//문서에 도달하면 중지하세요. 그렇지 않으면 무한 루프가 됩니다
if (parent.nodeType == 9) {
break;
}
//식별자 가져오기 또는 추가
uuid = parent.getAttribute('data-find')
if (!uuid) {
uuid = '_' (카운터); //크롬 재정렬 해시 방지
parent.setAttribute('data-find', uuid)
}
//증가 count
if (hash[uuid]) {
hash[uuid].count ;
}
else {
hash[uuid] = {노드: 상위, 개수: 1}; 🎜>}
node = parent;
}
}
//해시에는 각 노드가 위쪽으로 통과한 상위 노드만 포함되며 크기가 너무 커서는 안 됩니다
//그래서 이 루프는 상대적으로 빠릅니다.
for (i in hash) {
if (hash[i].count == length) {
return hash[i].node
}
}
};


댓글
테스트에는 문제가 없지만 테스트 케이스가 완벽한지 말하기는 어렵습니다. 네티즌들이 문제를 찾는 데 도움을 주셨으면 좋겠습니다. 100% 괜찮다고 말하는 자신감.
부모 요소를 얻으려면 IE와의 호환성을 위해 parentElement || parentNode를 작성하는 것이 일반적입니다. 이는 IE의 BUG 때문입니다. 요소가 방금 생성되었지만 DOM에 들어가지 않은 경우 해당 parentNode가 존재하지 않습니다. . 그러나 이 함수는 노드가 DOM 트리에 있는지 확인합니다. 실제로 parentElement는 필요하지 않습니다. 그러므로 때로는 습관적으로 호환되는 코드가 반드시 좋은 것은 아닙니다. 현재 환경에 가장 적합한 코드는 좋은 코드입니다.
이중 루프가 불가피하다고는 하지만, 특정 상황에서는 여전히 더 적은 작업을 수행할 수 있는 방법이 있다는 막연한 느낌이 듭니다. 예를 들어 위로 이동하면 특정 요소가 의 공통 조상이 될 수 없다는 것을 알게 됩니다. 모든 요소를 ​​삭제한 다음 더 이상 개수 값을 증가시키지 마세요.
마지막 for..in 루프를 생략할 수 있는 방법이 있나요? 위의 이중 루프에서 실시간으로 항상 가장 적절한 노드를 변수를 통해 저장하는 방법이 있나요?
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.