본문 바로가기
프로그래밍/jQuery

jQuery API 정복 - 요소 복사하기, clone()

by zoo10 2011. 11. 22.

.clone()

원문 링크 http://api.jquery.com/clone/

.clone()Returns : jQuery

개요 : 함수는 일치하는 요소 집합의 깊은 복사(deep copy)를 합니다.

  • .clone( [withDataAndEvents] )
  • withDataAndEvents 이벤트처리기에서 요소와 함께 복사를 할건지를 결정하는 부울값.
  • .clone( [withDataAndEvents,] [deepWithDataAndEvents] )
  • withDataAndEvents 이벤트 핸들러와 데이터 요소와 함께 복사해야하는지 여부를 나타내는 부울값. 기본값은 false.
  • deepWithDataAndEvents 이벤트 처리기와 복제된 요소의 모든 자식 요소 데이터를 복사해야하는지 여부를 결정하는 부울값. 기본값은 첫 번째 인수의 값과 일치.

.clone() 함수는 선택된 요소 집합을 깊은 복사(deep copy)할 수 있는 기능을 합니다. 깊은 복사(deep copy)의 의미는 선택된 요소들의 모든 자식 요소들과 텍스트 노드들을 모두 포함하는 것입니다. 끼워넣기 위한 함수의 용도로 사용될 때, .clone() 함수는 페이지 상에 요소들을 복사하여 넣기에는 아주 편한 방법입니다. 다음 HTML을 보도록 하겠습니다.

<div class="container">
  <div class="hello">Hello</div>
  <div class="goodbye">Goodbye</div>
</div>

.append() 함수와 비교가 필요한데, 일반적으로는 DOM에 특정 요소를 추가하는 부분에서는 같은 동작을 합니다. 단 그 추가 방법에 차이가 있는데요. .append() 함수는 원본에서 새로운 위치로 이동이 됩니다. 예를 들면

$('.hello').appendTo('.goodbye');

와 같이 스크립트를 작성하면 DOM 구조는 아래와 같이 바뀝니다.

<div class="container">
  <div class="goodbye">
    Goodbye
    <div class="hello">Hello</div>
  </div>
</div>

이러한 상황을 방지하고 새로운 요소를 복사를 통해 새로 생성해 내려면 아래와 같이 스크립트를 구성합니다.

$('.hello').clone().appendTo('.goodbye');

결과는요.

<div class="container">
  <div class="hello">Hello</div>
  <div class="goodbye">
    Goodbye
    <div class="hello">Hello</div>
  </div>
</div>

분명 차이가 있습니다. 차이점을 이해하시겠습니까?

Note .clone() 함수를 사용할 때, 당신은 복사한 요소에 새로운 요소를 첨가하여 변경 시킨 후 추가할 수도 있습니다.

일반적으로, 어떤 요소에 묶인(바인딩) 이벤트 처리기(event handlers)는 복사되지는 않습니다. 하지만 withDataAndEvents 요소를 사용하면 이런 속성을 바꿀 수 있습니다. 이런 방법을 쓰면 이벤트 핸들러를 복제할 수 있을 뿐만 아니라, 요소를 복사할 때 이벤트 핸들러를 새로운 요소에 묶을수도 있습니다. jQuery 1.4에 와서, 모든 요소 데이터도 새로 복사됩니다. (.data() 함수로 인해 연결된 것도).

하지만, 객체(objects) 와 배열(arrays) 는 요소 데이터 내부에 복사되지 않고 복사된 요소와 원본 요소 사이에 공유되게 됩니다. 깊은 복사를 하려면 수동으로 하나씩 해야 합니다.

var $elem = $('#elem').data( "arr": [ 1 ] ), // 붙여진 데이터의 원본 요소
    $clone = $elem.clone( true )
    .data( "arr", $.extend( [], $elem.data("arr") ) ); // 데이터 공유를 방지하기 위해 깊은 복사

예 제  
모든 b 태그 요소를 복사합니다.

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  
  <b>Hello</b><p>, how are you?</p>

<script>
  $("b").clone().prependTo("p");
</script>

</body>
</html>

미리보기

복사한 후 p 태그 앞에 놓기 위해 prependTo()를 사용한 것을 보실 수 있습니다.

 

예 제  
clone() 함수를 사용해서 요소 집합을 복사해서 삽입할 때 원래의 순서대로 복사될 거라는 보장은 없습니다. 하지만, 아래 예제처럼 사용한다면 순서를 보장받을 수 있습니다.

<!DOCTYPE html>
<html>
<head>
  <style>
  #orig, #copy, #copy-correct {
    float: left;
    width: 20%;
  }
</style>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  
<div id="orig">
    <div class="elem"><a>1</a></div>
    <div class="elem"><a>2</a></div>
    <div class="elem"><a>3</a></div>
    <div class="elem"><a>4</a></div>
    <div class="elem"><a>5</a></div>
</div>
<div id="copy"></div>
<div id="copy-correct"></div>

<script>
// sort order is not guaranteed here and may vary with browser  
$('#copy').append($('#orig .elem')
          .clone()
          .children('a')
          .prepend('foo - ')
          .parent()
          .clone()); 
 
// correct way to approach where order is maintained
$('#copy-correct')
          .append($('#orig .elem')
          .clone()
          .children('a')
          .prepend('bar - ')
          .end()); 
</script>

</body>
</html>

미리보기

음. 먼저 심오한 예제인 것 같은데 글쎄~~ 흠.. 어쨌든 그렇답니다.

 

그럼 즐프하세요.

※ 본 예제는 http://www.jquery.com 에 있는 내용임을 밝힙니다.