2012-12-13 6 views
7

Backbone.js 앱에서 documentFragments를 사용하여보고 있는데, documentFragment를 부모 DOM 요소에 추가 할 때 "cloneNode"가 사용되는 예제가 왜 표시되는지 궁금합니다.documentFragment를 추가 할 때 cloneNode를 사용해야하는 이유는 무엇입니까?

예는 here입니다. 당신이 DocumentFragment가 섹션에서 아래를 보면이 나타납니다 :

oFrag = document.createDocumentFragment(); 
for (var i = 0, imax = aElms.length; i < imax; i++) { 
oFrag.appendChild(aElms[i]); 
} 

o.innerHTML = ''; 
o.appendChild(oFrag.cloneNode(true)); 

왜 "oFrag는"대신에 그냥 추가로 복제됩니까? 다른 blog post은 (비교로서) "cloneNode"를 사용하지 않습니다.

+0

1 :

나는 조각을 캐싱 대 documentFragments를 재현과 복제의 성능 차이를 설명하기 위해 jsperf 조각을 만들었습니다. 내 유일한 (그리고 아주 야생) 추측은'cloneNode' 사용법이'oFrag' 스코프를 더 잘 제어 할 수 있다는 것입니다. – raina77ow

+0

나는 이것이 완전한 대답으로 위조 될 가치가 있다고 생각하지 않는다. 그러나 어쨌든 ... 단순히 'documentFragment cloneNode'를 찾음으로써 [이 게시물] (http://ejohn.org/blog/dom- documentfragments /)의 John Resig.)이 게시물의 주제에서 많은 수의 노드가 DOM에 여러 번 삽입되어야하므로 documentFragment를 복제하는 것이 실제로 더 나은 선택입니다. – raina77ow

답변

5

당신 first linkblog post 지칭 http://jsperf.com/cloning-fragments :-) 확인해. 당신은 여러 요소하려는 경우 : 같은 documentFragment 부여하는 (즉 된 div), 당신이 그것을 복제해야합니다

을 아이가 문서에있는 기존 노드에 대한 참조 인 경우에 appendChild에 현재 위치에서 이동 새로운 위치 (즉, 다른 노드에 노드를 추가하기 전에 노드를 부모 노드에서 제거 할 필요가 없음).

이렇게하면 노드가 문서의 두 지점에 동시에있을 수 없습니다. 따라서 노드에 이미 상위가있는 경우에는 먼저 제거 된 다음 새 위치에 추가됩니다. MDN

대부분의 경우를 통해

저자 (또는 다른 사람) 복사 - 붙여 넣기이를 고려하지 않고 코드를. 직접 시도하십시오 - cloneNode없이 appendChild을 사용할 수 있으며 모든 것이 잘 동작합니다.

또 다른 가능성은 jsperf에서이 테스트 케이스를 작성한 사람이 준비 코드가 작동하는 방식을 많이 얻지 못했기 때문에 첫 번째 테스트가 aElms 어레이를 비우고 더 이상 작동하지 않을까 우려했다는 것입니다. In fact 준비 코드는 각 시간 지정된 반복 전에 실행되기 때문에 그 내용에 대해 걱정할 필요가 없습니다.

마지막으로 성능 문제가있을 수 있습니다. 실제로 실제 삽입을 테스트하려면 노드를 복제해야합니다. 그렇지 않으면 재 부착 트리를 대신 테스트하십시오 (위의 MDN 링크 참조).

또한 cloning destroys event listeners에 유의하십시오.

해피 fragmentin '! ;)

2

정확하지는 않지만 제공 한 링크 (성능 테스트)에서 oFrag.cloneNode(true)은 이전 루프 실행에서 이미 DOM에 추가 된 요소를 재사용하는 것을 막을 수 있습니다. 빠른 테스트 실행.

documentFragments의 일반적인 사용 사례에는 사용할 이유가 없습니다.

+0

+1 그게 사실이라고 생각합니다. – raina77ow

0

나는 그것이 필요하지 않다고 생각한다. 나는 을 정적으로 참조에서 분리하는 데에만 사용되었으며, appendChild을 호출 할 때 이전 부모로부터 제거해야 할 필요가 있었던 것으로 추정됩니다. 이 테스트에서는 성능 향상을 위해서만 사용됩니다. 그러나

,합니다 (appendChild 테스트에 더 유사) 다음 코드는 나에게 더 나을 :

var oFrag = document.createDocumentFragment(); 
for (var i = 0, imax = aElms.length; i < imax; i++) 
    oFrag.appendChild(aElms[i].cloneNode(true)); 
// using it here:    ^^^^^^^^^^^^^^^^ 
o.appendChild(oFrag); 

이 한 번만 전체 조각, 노드 트리를 호출하는 것보다 느려질 수 있습니다 있지만 네이티브 코드로 되살아 난다.

또한 autor 테스트 경우에서처럼 document.getElementsByTagName document.getElementById 대신 사용하는 곳

2

documentFragment를 요소에 추가하고 나중에 해당 요소에서 추가 된 노드를 지우면 documentFragment도 비어있어 더 이상 재사용 할 수 없습니다. documentFragment의 복제본을 추가하면이 문제를 방지하고 documentFragment를 여러 번 재사용 할 수 있습니다.

필자는 jsperf 스 니펫의 작성자가 이러한 경우에 대해 테스트했다고 가정합니다.

예 : 부모 - 자식 관계가있는 드롭 다운. 대륙을 선택할 때 드롭 다운이 있고 그 대륙에있는 모든 국가를 나열하는 두 번째 드롭 다운이 있다고 가정 해 보겠습니다. 생성 후 옵션 노드를 사용하여 생성 된 documentFragments를 캐시하려면 cloneNode를 사용해야합니다. 누군가가 유럽을 선택한 다음 아프리카를 선택한 다음 유럽을 다시 선택한다고 가정 해보십시오. 전체 문서 조각을 다시 만들거나 캐시 할 수 있습니다. 매우 흥미로운 사실 ​​

http://jsperf.com/documentfragment-cache-vs-recreate

+0

감사합니다. 꽤 재미 있습니다. – codecraig

관련 문제