jquery 구현 원리 7: DOM 스트리밍-tranversing
3704 단어 jqueryjquery 실현 원리jquery 소스 분석
tranversing 전에pushStack 함수를 언급해야 합니다. 이 함수는dom 작업에서 여러 번 사용되었습니다.이 함수는 매우 간단하게 실현된다.
// Take an array of elements and push it onto the stack
// (returning the new matched element set)
pushStack: function( elems ) {
// Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems );
// Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context;
// Return the newly-formed element set
return ret;
},
merge: function( first, second ) {
var l = second.length,
i = first.length,
j = 0;
if ( typeof l === "number" ) {
for ( ; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
} else {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
}
first.length = i;
return first;
},
편의를 위해merge함수도 붙였다.
우선merge함수의 작용은 매우 간단하다.second의 원소를 모두first에 추가하는 것이다.
그리고 pushStack이 무엇을 했는지 한 줄 한 줄 보고,
1, var ret = jQuery.merge( this.constructor(), elems ); 이 코드는 빈 jquery 대상을 새로 만들고 elemsmerge를 넣었기 때문에 이것은 var ret = $(elems)에 해당합니다.(왜 직접 이렇게 쓰지 않고 복잡하게 만드는지 성능 때문인지 모르겠다)
2,ret.prevObject = this; ret.context = this.context; 속성prevObject를 설정했습니다. 이 속성은pushStack 이전의query 대상을 저장합니다. 따라서query 대상을 여러 번 찾으면prevObject를 따라 되돌아갈 수 있습니다. 예를 들어 $('xx ').find('a').prevObject.xxx.context는 상하문을 기록하는 것으로 여러 window에서 사용할 수 있으며 상관하지 않아도 됩니다.
마지막으로ret로 돌아왔습니다.
그래서 총괄적으로 말하면pushStack 함수의 역할은 새로운 jquery 대상을 되돌려주는 것이다. 단지prevObject로 지난번에 선택한 대상을 기록할 뿐이다.
둘째, traversing 실현 원리
이 모듈은 단지 200여 줄의 코드만 있어서 매우 이해하기 쉬우므로 너무 많은 설명을 할 필요가 없다.
기본 구조를 말해 보세요. 코드 구조가 좋지 않으면 중복되는 코드가 많을 수 있으니까요.
우선, 가장 핵심적인 것은 다음과 같은 세 가지 함수이다.
jQuery.extend({
filter: function( expr, elems, not ) {
var elem = elems[ 0 ];
if ( not ) {
expr = ":not(" + expr + ")";
}
return elems.length === 1 && elem.nodeType === 1 ?
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
return elem.nodeType === 1;
}));
},
dir: function( elem, dir, until ) {
var matched = [],
truncate = until !== undefined;
while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
if ( elem.nodeType === 1 ) {
if ( truncate && jQuery( elem ).is( until ) ) {
break;
}
matched.push( elem );
}
}
return matched;
},
sibling: function( n, elem ) {
var matched = [];
for ( ; n; n = n.nextSibling ) {
if ( n.nodeType === 1 && n !== elem ) {
matched.push( n );
}
}
return matched;
}
});
사실 작용과 실현은 모두 일목요연하다.
Filter는elems에서expr에 맞는 결과를 필터합니다
dir는 한 방향으로 옮겨다니는 것입니다. 예를 들어parentNode입니다. 끝날 때까지 옮겨다니는 조건은until입니다.
bling은 형제 노드를 두루 훑어보고 elem까지 두루 훑어본다. 이곳의 elem과dir의 until은 같은 작용을 한다. 모두 끝 요소이다. until이라고 불러야 하지 않겠는가?
그리고api를 정의했습니다. 모두 이 세 가지 함수를 호출해서 이루어진 것이기 때문에 할 말이 없고 더 이상 말하지 않겠습니다.
그 중의 실현, 어떻게 최대한의 복용 코드를 사용하는지 주의해라.
예를 들어 Filter와 not의 기능이 매우 비슷해서 이를 winnow 함수에 봉인했다.parent,next,prev 등 한 무더기의 함수도 매우 비슷하여 서로 다른 부분을 대상에 존재하고 이 대상을 옮겨다니며 인터페이스를 생성한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
jQuery 전후 예이 기사에서는 jquery after() 및 before() 메소드의 예를 볼 것입니다. before() 메서드는 선택한 요소 앞에 지정된 콘텐츠를 삽입합니다. after() 메서드는 선택한 요소 뒤에 지정된 콘텐츠...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.