Удаление, замена и перемещение элементов в jQuery

В данном уроке рассматриваются вопросы манипулирования существующими элементами на странице:

  • Удаление элементов со страницы с помощью методов empty(), remove(), detach() и unwrap()
  • Замена элементов новыми элементами с помощью методов replaceWith() и replaceAll()
  • Перемещение элементов от одного родительского элемента к другому на странице

Удаление элементов со страницы

Удаление всего, что находится внутри элемента: empty()

Метод empty() - это простейший способ удаления содержимого со страницы. Вызов метода empty() для объекта jQuery удаляет все содержимое из набора, соответствующего элементу (или элементам) в объекте jQuery.

Другими словами, метод empty() удаляем все наследственные элементы и узлы (такие, как текстовые узлы) из каждого элемента, попадающего в набор, оставляя элемент пустым.

В примере удаляется содержимое из двух элементов div:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">

$( init );

function init() {

  // Удаляем содержимое #myDiv1 и #myDiv2
  $('.emptyMe').empty();
}

</script>

</head>
<body>

  <div class="emptyMe" id="myDiv1">
    <p>Параграф с текстом</p>
  </div>

  <div class="emptyMe" id="myDiv2">
    <p>Другой параграф с текстом</p>
    Текстовый узел, как он есть
  </div>

</body>
</html>

После выполнения выше приведённого кода содержимое страницы изменится на :

<body>
  <div class="emptyMe" id="myDiv1" />
  <div class="emptyMe" id="myDiv2" />
</body>

Удаление элемента целиком: remove()

Если метод empty() удаляет всё внутри элемента, то метод remove() удаляет все, включая сам элемент. Например:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">

$( init );

function init() {

  // Удаляем #myDiv1 и #myDiv2 целиком
  $('.removeMe').remove();
}

</script>

</head>
<body>

  <div class="removeMe" id="myDiv1">
    <p>Параграф с текстом</p>
  </div>

  <div class="removeMe" id="myDiv2">
    <p>Другой параграф с текстом</p>
    Текстовый узел, как он есть
  </div>

</body>
</html>

после выполнения выше приведённого кода оба элемента div будут удалены со страницы:

<body>
</body>

Вы можете передать строку с условным селектором в метод remove(). В этом случае, удаляемые элементы будут фильтроваться селектором. Например:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">

$( init );

function init() {

  // Удаляем только #myDiv2
  $('.removeMe').remove(':contains("Другой параграф")');
}

</script>

</head>
<body>

  <div class="removeMe" id="myDiv1">
    <p>Параграф с текстом</p>
  </div>

  <div class="removeMe" id="myDiv2">
    <p>Другой параграф с текстом</p>
    Текстовый узел, как он есть
  </div>

</body>
</html>

В выше приведённом примере будет удалён только элемент div, для которого установлен класс removeMe и содержащий текст "Другой параграф". Все остальное останется на странице:

<body>

  <div class="removeMe" id="myDiv1">
    <p>Параграф с текстом</p>
  </div>

</body>

Удаление элемента без разрушения его данных: detach()

Метод remove() возвращает объект jQuery, который содержит удалённые элементы. Теоретически, можно удалить какие-нибудь элементы из одного места на странице, а позже снова присоединить их где угодно..

Однако, для того, чтобы сохранить ресурсы и избежать потенциальной проблемы с утечкой памяти, метод remove() удаляет все данные jQuery и события, ассоциированные с удалённым элементом. Например, если элементу было назначено событие jQuery click, а затем элемент был удалён со страницы с помощью метода remove(), то событие click будет удалено из элемента. Это может вызвать проблему, если позже захотите вернуть элемент обратно на страницу и восстановить его функциональность.

В данном случае может помочь метод detach() (появился в jQuery 1.4). Он действует почти также как и метод remove(), за исключением одного - он не удаляет данные jQuery и события, ассоциированные с удалённым элементом. Это означает, что позже вы можете присоединить удалённые элементы обратно с сохранением их метаданных jQuery.

Пример. Следующий скрипт назначает событие jQuery click каждому из двух параграфов на странице. Оба обработчика события просто переключают класс CSS "red" для параграфа, чтобы изменить цвет с красного на чёрный или обратно каждый раз, когда на него нажимают.

Затем скрипт удаляет первый параграф со страницы с использованием метода remove() и сохраняет объект jQuery , который содержал параграф в переменной myDiv1Para. Затем повторно присоединяем параграф к родительскому div с помощью метода appendTo().

Тоже самое мы проделываем со вторым параграфом, только используем метод detach() вместо метода remove().

<
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>

<style>p.red { color: red; }</style>

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$( init );

function init() {

  // Назначаем событие click каждому параграфу div
  $("#myDiv1>p").click( function() { $(this).toggleClass("red"); } );
  $("#myDiv2>p").click( function() { $(this).toggleClass("red"); } );

  // Удаляем и восстанавливаем параграф #myDiv1
  var myDiv1Para = $('#myDiv1>p').remove();
  myDiv1Para.appendTo('#myDiv1');

  // Удаляем и восстанавливаем параграф #myDiv2
  var myDiv2Para = $('#myDiv2>p').detach();
  myDiv2Para.appendTo('#myDiv2');
}

</script>

</head>
<body>

  <div id="myDiv1">
    <p>Параграф с текстом</p>
  </div>

  <div id="myDiv2">
    <p>Другой параграф с текстом</p>
  </div>

</body>
</html>

После выполнения данного скрипта первый параграф потеряет обработчик события click, а второй параграф сохранит свою функциональность полностью. Вы можете проверить, открыв страницу в браузере. Если нажать кнопку мыши на втором параграфе, то он будет менять цвет, а первый никак не будет реагировать на действия мыши.

Это происходит потому, что вызов метода remove() привёл к удалению обработчика события для первого параграфа, а метод detach() сохранил обработчик события click для второго параграфа.

Далее мы рассмотрим ещё несколько способов переместить элемент.

Удаление родительского элемента: unwrap()

Метод unwrap() удаляет родителя элемента (или родителей набора элементов)из DOM. Элемент займёт место родительского элемента в DOM.

Следующий пример разворачивает содержание div. Другим словами происходит замещение div его содержимым:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">

$( init );

function init() {

  // Удаляем элемент #myDiv, но сохраняем его содержимое
  $('#myPara').unwrap();
}

</script>

</head>
<body>

  <div id="myDiv">
    <p id="myPara">Параграф с текстом</p>
    <p>Другой параграф с текстом</p>
  </div>

</body>
</html>

После выполнения выше приведённого кода, содержание страницы примет следующий вид:

<body>

  <p id="myPara">Параграф с текстом</p>
  <p>Другой параграф с текстом</p>

</body>

Замена элементов

Замена элемента новым содержимым: replaceWith()

Метод replaceWith() позволяет заменять элемент или набор элементов новым содержимым. Вы можете передать замещающий контент в любой из следующих форм:

  • Объект элемента, который создан с помощью функции JavaScript DOM, такой как document.getElementById() или document.createElement()
  • Строка HTML, представляющая замещающий контент
  • Объект jQuery, содержащей элемент (или элементы), который будет использоваться для замещения
  • Возвратная функция, которая должна возвращать замещающий HTML код

Ниже приводится пример, который показывает метод replaceWith() в действии. Производится замещение первого параграфа новой строкой HTML, второй параграф замещается объектом элемента, а третий параграф заменяется результатом функции, которая возвращает текущее время:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">

$( init );

function init() {

  // Заменяем параграф в #myDiv1 новым параграфом
  $('#myDiv1>p').replaceWith( "<p>Новый параграф с текстом</p>" );

  // Заменяем параграф в #myDiv2 горизонтальной линией
  var hr = document.createElement('hr');
  $('#myDiv2>p').replaceWith( hr );

  // Заменяем параграф в #myDiv3 строкой с текущим временем
  $('#myDiv3>p').replaceWith( currentTime );

  function currentTime() {
    var currentTime = new Date();
    var currentHours = currentTime.getHours ( );
    var currentMinutes = currentTime.getMinutes ( );
    var currentSeconds = currentTime.getSeconds ( );

    // Pad the minutes and seconds with leading zeros, if required
    currentMinutes = ( currentMinutes < 10 ? "0" : "" ) + currentMinutes;
    currentSeconds = ( currentSeconds < 10 ? "0" : "" ) + currentSeconds;

    return ( "<p>Текущее время: " + currentHours + ":" + currentMinutes + ":" + currentSeconds + "</p>" );
  }
}

</script>

</head>
<body>

  <div id="myDiv1">
    <p>Параграф с текстом</p> 
  </div>

  <div id="myDiv2">
    <p>Параграф с текстом</p>
  </div>

  <div id="myDiv3">
    <p>Параграф с текстом</p>
  </div>

</body>
</html>

После выполнения кода содержимое страницы примет вид :

<body>

  <div id="myDiv1">
    <p>Новый параграф с текстом</p> 
  </div>

  <div id="myDiv2">
    <hr />
  </div>

  <div id="myDiv3">
    <p>Текущее время: 13:52:17</p>
  </div>

</body>

replaceAll(): альтернатива методу replaceWith()

Метод replaceAll() выполняет туже самую работу, что и метод replaceWith(), но вместо передачи замещающего контента в качестве аргумента, вам нужно передать элемент, который нужно заменить.

Например, следующие 2 строки кода делают одно и тоже:

$('#myDiv').replaceWith( "<p>Здесь новый текст</p>" );
$("<p>Здесь новый текст</p>").replaceAll( '#myDiv' );

Перемещение элементов

Теперь вы знаете, как удалять и заменять элементы. Остаётся открытым вопрос: как перемещать элементы по дереву DOM? Например, есть параграф внутри элемента div, и нужно его переместить в другой div.

Несмотря на то, что в jQuery нет специального метода для перемещения элементов по дереву DOM, в действительности это очень просто реализовать. Все, что нужно сделать, это выделить элемент(ы), которые вы хотите переместить; затем вызвать метод "добавления" , например, append(), appendTo() или prepend(), чтобы добавить выделенный элемент к другому родительскому элементу. jQuery автоматически распознает, что элемент(ы) уже существует на странице и переместит его к новому родителю.

Пример воспроизводит описанный процесс. Параграф перемещается из первого div во второй:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">

$( init );

function init() {

 // Перемещаем параграф из #myDiv1 в #myDiv2
  $('#myDiv2').append( $('#myDiv1>p') );
}

</script>

</head>
<body>

  <div id="myDiv1">
    <p>Параграф с текстом</p> 
  </div>

  <div id="myDiv2">
  </div>

</body>
</html>

После выполнения кода страница примет следующий вид:

  <div id="myDiv1">
  </div>

  <div id="myDiv2">
    <p>Параграф с текстом</p>   
  </div>

А здесь другой способ перемещения элемента:

  // Перемещаем параграф из #myDiv1 в #myDiv2
  $('#myDiv1>p').appendTo( $('#myDiv2') );

  // Пермещаем параграф из #myDiv1 в #myDiv2
  var para = $('#myDiv1>p');
  para.prependTo( '#myDiv2' );

  // Перемещаем параграф из #myDiv1 в #myDiv2
  // с помощью явного отсоединения его и добавления в новое место
  $('#myDiv1>p').detach().prependTo('#myDiv2');

З-й пример демонстрирует очень полезную технику jQuery — связывание методов. Так как большинство методов jQuery возвращает объекты, то можно вызывать другой метод для возвращаемого объекта. Что в свою очередь приведёт к возвращению следующего объекта jQuery и так далее.

Так в выше приведённом примере объект jQuery возвращается методом detach(), который вызывается для удаления параграфа. А метод prependTo() вызывается для возвращённого объекта jQuery, чтобы добавить удалённый параграф к новому родительскому элементу.

Что произойдёт, если попытаться переместить какой-нибудь контент в более чем один родительский элемент в одно и то же время? Если это сделать, jQuery сначала удалит контент из старого родителя, затем клонирует контент столько раз, сколько нужно и добавит клоны в каждый указанный родительский элемент. Например:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">

$( init );

function init() {

 // Перемещаем параграф из #myDiv1 в #myDiv2 и #myDiv3
  $('#myDiv2, #myDiv3').append( $('#myDiv1>p') );
}

</script>

</head>
<body>

  <div id="myDiv1">
    <p>Параграф с текстом</p> 
  </div>

  <div id="myDiv2">
  </div>

  <div id="myDiv3">
  </div>

</body>
</html>

После выполнения выше описанного кода, содержимое страницы будет выглядеть так:

<body>

  <div id="myDiv1">
  </div>

  <div id="myDiv2">
    <p>Параграф с текстом</p>   
  </div>

  <div id="myDiv3">
    <p>Параграф с текстом</p>   
  </div>

</body>

Резюме

Удаление, замена и перемещение контента являются фундаментальными концепциями, которые позволяют строить замечательные сайты на основе jQuery.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: www.elated.com/articles/jquery-removing-replacing-moving-elements/
Перевел: Сергей Фастунов
Урок создан: 11 Августа 2010
Просмотров: 267416
Правила перепечатки


5 последних уроков рубрики "jQuery"

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 12 Августа 2010 00:05
    dmitry
    Отличный урок! Молодцы!
  • 12 Августа 2010 10:21
    Serega
    спасибо за урок
  • 13 Августа 2010 06:03
    Alexxhub
    Хотелось бы конечно еще урок по добавлению новых элементов средствами jQuery. Как например мне добавить определенный кусок кода после второго тега <p>? <p>&nbsp</p> <p>&nbsp</p> <А сюда допустим автоматом вставляется код банера> <p>&nbsp</p>
  • 13 Августа 2010 07:01
    Жека
    Я так понимаю последние уроки посвящены jQuery в связи со скорым релизом нового курса Евгения Попова ;)
  • 14 Августа 2010 04:28
    Denisido
    Автору: Alexxhub $(function() { $('p:eq(1)').after('<b>твой банер</b>'); }); // end ready
  • 14 Августа 2010 04:30
    Denisido
    Ай ай меры пердосторожности здесь - это хорошо. Скрипт со слэшами в общем если хочешь посмотреть, то пример здесь: http://templateworld.narod.ru/test/t-4.html просто посмотри исходный код! Удачи!
  • 16 Августа 2010 07:52
    Alexxhub
    Спасибо уважаемый
  • 3 Августа 2011 14:06
    wanre
    норм!!!!
  • 17 Декабря 2011 16:29
    l2cri
    	<!DOCTYPE html>	<html xmlns="http://www.w3.org/1999/xhtml">	<head>	<style>p.red { color: red; }</style>	<script type="text/javascript" src="jquery.js"></script>	<script type="text/javascript">	$( init );	function init() { // Назначаем событие click каждому параграфу div $("#myDiv1>p").click( function() { $(this).toggleClass("red"); } ); $("#myDiv2>p").click( function() { $(this).toggleClass("red"); } ); // Удаляем и восстанавливаем параграф #myDiv1 var myDiv1Para = $('#myDiv1>p').remove(); myDiv1Para.appendTo('#myDiv1'); // Удаляем и восстанавливаем параграф #myDiv2 var myDiv2Para = $('#myDiv2>p').detach(); myDiv2Para.appendTo('#myDiv2');	}	</script>	</head>	<body> <div id="myDiv1"> <p>Параграф с текстом</p> </div> <div id="myDiv2"> <p>Другой параграф с текстом</p> </div>	</body>	</html>
    В общем не работает это. Во первых откуда $("#myDiv1>p") и $("#myDiv2>p")у нас же div id myDiv1 и myDiv2 ? Потом очень интересно в style обьявили p.red опять же у нас вызывается style class red, а его нету.Для конкретного элемента обычно применяют #red p{color:red} ну и тогда вызывается id=:"red" и тогда все <p> окрасятся
  • 7 Октября 2012 09:53
    gabderakhmanov
    спасибо за урок, очень помог!
  • 20 Мая 2015 17:09
    Chelios
    Спасибо большое за урок! Но подскажите такой момент: Удаляю методом remove() div, но при перезагрузке (на денвере по крайней мере) содержимое дива все же сначала появляется, потом исчезает. Происходит это очень быстро, но глазом заметно. Цель не дать ни пользователям увидеть ни поисковику проиндексировать содержимое дива, но и совсем избавиться от него нельзя (функционально нужен). Так как поведет себя ПС в данном случае? А убрать надо около сотни дивов из кода.
    • 14 Июля 2015 14:09
      Алексей Степанов
      Вы же удаляете элемент из DOM - из модели документа, в исходном коде страницы элемент остается. А поисковый робот вообще скорей всего не исполняет JavaScript, так что он ваш удаленный блок увидит. Не тот вы метод выбрали для решения такой задачи.
  • 10 Октября 2015 05:17
    l2cri
    Удалите мой предыдущий комментарий, я был тупым
  • 31 Августа 2016 08:40
    Gald
    Подскажите, пожалуйста, как быть с методами «remove» и «empty». Когда загружается страница, скрипт начинает удалять элемент или его содержимое только после полной загрузки этого элемента или его содержимого: различные медиафайлы. А нужно чтобы удаление происходило сразу, как только был загружен скрипт и разметка страницы еще до полной загрузки контента. Есть ли альтернативные решения?
^ Наверх ^