Создание JQuery-плагина поиска и замены. JQuery: замена элемента, его вложение, перемещение и другие действия

В настоящий момент ситуация такова, что все больше и больше разработчиков приходят в мир JavaScript через ворота jQuery. И новички являются счастливчиками. Они получают доступ к изобилию новых API JavaScript, которые делают процесс работы с DOM существенно легче. Но, к сожалению, они не имеют представления об этих API! В данном уроке мы рассмотрим несколько типовых задач, которые решаются средствами jQuery, и преобразуем решения в обычный JavaScript.

В уроке будут приводиться два варианта решения - модерн и наследие. Решения типа "модерн" представляют собой новейшие методы, а "наследие" демонстрирует то, что будет нравиться старым браузерам. Выбор варианта зависит от разработчика веб проекта и целевой аудитории.

Вступление

Обратите внимание, что некоторые варианты из набора "наследие" в данной статье используют простую, кросс-браузерную функцию addEvent . Данная функция нормализует два варианта - рекомендованную W3C модель событий addEventListener и вариант для Internet Explorer attachEvent .

Когда используется функция addEvent(els, event, handler) в коде, она представляет собой следующий код:

Var addEvent = (function () { var filter = function(el, type, fn) { for (var i = 0, len = el.length; i < len; i++) { addEvent(el[i], type, fn); } }; if (document.addEventListener) { return function (el, type, fn) { if (el && el.nodeName || el === window) { el.addEventListener(type, fn, false); } else if (el && el.length) { filter(el, type, fn); } }; } return function (el, type, fn) { if (el && el.nodeName || el === window) { el.attachEvent("on" + type, function () { return fn.call(el, window.event); }); } else if (el && el.length) { filter(el, type, fn); } }; })(); // Использование addEvent(document.getElementsByTagName("a"), "click", fn);

1 - $("#container");

Данная функция обращается к DOM для получения элемента с идентификатором container и создает новый объект jQuery .

Модерн

Var container = document.querySelector("#container");

querySelector является частью API Selectors , которая обеспечивает возможность обращения к DOM с помощью селекторов CSS.

Данный метод возвращает первый элемент, который соответствует переданному селектору.

Наследие

Var container = document.getElementById("container");

2 - $("#container").find("li");

В данном случае мы получаем любое количество пунктов списка, которые являются потомками элемента #container .

Модерн

Var lis = document.querySelectorAll("#container li");

querySelectorAll возвращает все элементы, которые соответствуют определенному CSS селектору.

Ограничения. Хотя все браузеры поддерживают API Selectors, передача определенных селекторов CSS ограничивается возможностью браузера. Например: Internet Explorer 8 поддерживает только селекторы CSS 2.1.

Наследие

Var lis = document.getElementById("container").getElementsByTagName("li");

3 - $("a").on("click", fn);

В данном примере обработчик события click привязывается ко всем ссылкам на странице.

Модерн

ForEach.call(document.querySelectorAll("a"), function(el) { // на ссылку нажали });

Выше приведенный код выглядит ужасно, но он не так уж и плох. Так как querySelectorAll возвращает NodeList , а не массив, то мы не можем непосредственно использовать метод, например, forEach . Данный момент обходится вызовом forEach для объекта Array и передачей результата querySelectorAll как this .

Наследие

Var anchors = document.getElementsbyTagName("a"); addEvent(anchors[i], "click", fn);

4 - $("ul").on("click", "a", fn);

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

Модерн

Document.addEventListener("click", function(e) { if (e.target.matchesSelector("ul a")) { // Обработка } }, false);

Технически, данный метод JavaScript не является полным соответствием примеру jQuery. Он привязывает обработчик события непосредственно к document . А затем используется метод matchesSelector для определения того факта, что цель (узел, на котором произошло нажатие кнопки) соответствует указанному селектору. Таким образом, мы привязываем единственный обработчик события.

Обратите внимание, что на момент написания урока все браузеры реализовывали matchesSelector с использованием префиксов: mozMatchesSelector , webkitMatchesSelector , и так далее. Для нормализации метода, вы можете написать:

Var matches; (function(doc) { matches = doc.matchesSelector || doc.webkitMatchesSelector || doc.mozMatchesSelector || doc.oMatchesSelector || doc.msMatchesSelector; })(document.documentElement); document.addEventListener("click", function(e) { if (matches.call(e.target, "ul a")) { // Обработка } }, false);

Наследие

Var uls = document.getElementsByTagName("ul"); addEvent(uls, "click", function() { var target = e.target || e.srcElement; if (target && target.nodeName === "A") { // Обработка } });

Для обеспечения обратной совместимости мы проверяем, что свойство nodeName (имя целевого элемента) равно нашему запросу. Обратите внимание на факт, что старые версии Internet Explorer иногда играют своими собственными правилами. Вы не захотите получать доступ к цели непосредственно из объекта event . Зазочется использовать event.srcElement .

5 - $("#box").addClass("wrap");

jQuery обеспечивает удобный API для модификации имени класса для набора элементов.

Модерн

Document.querySelector("#box").classList.add("wrap");

Новая техника использует новый API classList для добавления, удаления и переключения класса (add , remove , и toggle).

Var container = document.querySelector("#box"); container.classList.add("wrap"); container.classList.remove("wrap"); container.classList.toggle("wrap");

Наследие

Box = document.getElementById("box"), hasClass = function (el, cl) { var regex = new RegExp("(?:\\s|^)" + cl + "(?:\\s|$)"); return !!el.className.match(regex); }, addClass = function (el, cl) { el.className += " " + cl; }, removeClass = function (el, cl) { var regex = new RegExp("(?:\\s|^)" + cl + "(?:\\s|$)"); el.className = el.className.replace(regex, " "); }, toggleClass = function (el, cl) { hasClass(el, cl) ? removeClass(el, cl) : addClass(el, cl); }; addClass(box, "drago"); removeClass(box, "drago"); toggleClass(box, "drago"); // Если элемент не имеет класса "drago", добавляем его.

Обратная совместимость требует достаточно много действий.

6 - $("#list").next();

Метод jQuery next возвращает элемент, который следует непосредственно за текущим элементом наборе.

Модерн

Var next = document.querySelector("#list").nextElementSibling; // IE9

nextElementSibling ссылается на следующий узел за элементом. К сожалению, Internet Explorer 8 и старше не поддерживают его.

Наследие

Var list = document.getElementById("list"), next = list.nextSibling; // Нам нужен следующий элемент, а не текст. while (next.nodeType > 1) next = next.nextSibling;

Есть пара способов для реализации задачи. В данном примере мы определяем тип узла nodeType , который следует на определенным элементом. Это может быть текст, элемент или, даже, комментарий. Так как нам нужен именно следующий элемент, то мы ищем nodeType равный 1 . Если next.nodeType возвращает номер больше, чем 1 , то мы пропускаем узел, так как он, вероятно, является текстом.

7 - $("").appendTo("body");

В дополнение к запросам DOM jQuery также предлагаем возможность создавать и вставлять элементы.

Модерн

Var div = document.createElement("div"); div.id = "box"; document.body.appendChild(div);

В данном примере нет ничего нового. Таким способом выполнялся процесс создания и вставки элемента в структуру DOM очень давно.

Вероятно, что вам понадобится добавить содержание в элемент. В данном случае вы можете использовать innerHTML или createTextNode .

Div.appendChild(document.createTextNode("wacka wacka")); // или div.innerHTML = "wacka wacka";

8 - $(document).ready(fn)

Метод jQuery document.ready невероятно удобен. Он позволяет нам выполнять код сразу по завершению загрузки DOM.

Модерн

Document.addEventListener("DOMContentLoaded", function() { // Наш код });

Стандартная часть HTML5, событие DOMContentLoaded генерируется после завершения анализа документа.

Наследие

// http://dustindiaz.com/smallest-domready-ever function ready(cb) { /in/.test(document.readyState) // in = loadINg ? setTimeout("ready("+cb+")", 9) : cb(); } ready(function() { // Получаем нужное из DOM });

Решение для обратной совместимости - каждые 9 миллисекунд мы проверяем значение document.readyState . Если возвращается “loading”, то документ все еще не загружен полностью (/in/.test()). Как только значение document.readyState будет равно “complete,” выполнится возвратная функция.

9 - $(".box").css("color", "red");

Если возможно, всегда добавляйте класс к элементу, когда нужно задать ему определенный стиль. Однако, иногда стили задаются динамически, и приходится вставлять атрибуты.

Модерн

ForEach.call(document.querySelectorAll(".box"), function(el) { el.style.color = "red"; // или добавляем класс });

Снова мы используем технику .forEach.call() для фильтрации всех элементов с классом box и придания им красного цвета с помощью объекта style .

Наследие

Var box = document.getElementsByClassName("box"), // смотрите пример 10 ниже для кросс-браузерного решения i = box.length; while (i-- > 0 && (box[i].style.color = "red"));

Мы используем трюк с циклом while . По существу, мы имитируем:

Var i = 0, len; for (len = box.length; i < len; i++) { box[i].style.color = "red"; }

Хотя нужно выполнить одно действие, мы можем сэкономить пару строк. Обратите внимание, что легкость чтения кода важнее сохранения пары строк кода.

10 - $()

Определенно, цель полностью заменить jQuery API выходит за рамки данного урока. Но часто в проектах функции $ или $$ используются для короткой записи получения одного или нескольких элементов из DOM.

Модерн

Var $ = function(el) { return document.querySelectorAll(el); }; // Использование = $(".box");

Это просто односимвольный указатель на document.querySelector . Сохраняет время!

Наследие

If (!document.getElementsByClassName) { document.getElementsByClassName = function(cl, tag) { var els, matches = , i = 0, len, regex = new RegExp("(?:\\s|^)" + cl + "(?:\\s|$)"); // Если не задано имен тегов, // мы будем получать все элементы из DOM els = document.getElementsByTagName(tag || "*"); if (!els) return false; for (len = els.length; i < len; i++) { if (els[i].className.match(regex)) { matches.push(els[i]); } } return matches; // массив элементов, которые имеют определённое имя класса }; } // Очень простая реализация. Проверяем id, класс и имя тега. var $ = function(el, tag) { var firstChar = el.charAt(0); if (document.querySelectorAll) return document.querySelectorAll(el); switch (firstChar) { case "#": return document.getElementById(el.slice(1)); case ".": return document.getElementsByClassName(el.slice(1), tag); default: return document.getElementsByTagName(el); } }; // Использование $("#container"); $(".box"); // Любые элементы с классом box $(".box", "div"); // Элементы div с классом box $("p"); // Получаем все элементы p

К сожалению, метод обратной достаточно большой. В данном случае лучше использовать библиотеку. jQuery оптимизирован для работы с DOM! Пример выше будет работать, но он не поддерживает сложные селекторы CSSв старых браузерах.

Сохраните эту страницу для тестирования приведенных ниже примеров.

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

С помощью методов, описанных в таблице ниже, можно заменить один набор элементов другим:

Методы replaceWith() и replaceAll() работают одинаковым образом, за исключением того, что объект jQuery и аргумент играют в них противоположные роли. Пример использования обоих методов приведен ниже:

$(function() { var newElems= $("") ..png"/>") .append("Орхидея:") .append("") .css("border", "thick solid red"); $("#row1").children().first()..png"/>").replaceAll("#row2 img") });

В этом сценарии сначала создается набор элементов, а затем в документе выполняется поиск элемента div, атрибут id которого равен row1, и его первый дочерний элемент заменяется новым содержимым с помощью метода replaceWith() (что в конечном счете приводит к замене элементов, соответствующих астрам, элементами, соответствующими орхидеям). Наконец, с помощью метода replaceAll() все элементы img, являющиеся потомками элемента, атрибут id которого равен row2, заменяются изображениями гвоздики.

Вид страницы в окне браузера представлен на рисунке:

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

$(function() { $("div.drow img").replaceWith(function() { if (this.src.indexOf("rose") >.png"/>").css("border", "thick solid red"); } else if (this.src.indexOf("peony") >.png"/>").css("border", "thick solid red"); } else { return $(this).clone(); } }); });

В этом сценарии мы выполняем замену элементов img на основании значений их атрибутов src. Если этот атрибут элемента img содержит rose, то данный элемент заменяется другим, которому соответствует изображение carnation.png. Если же атрибут src элемента содержит peony, то данный элемент заменяется другим, которому соответствует изображение lily.png. Оба замененных элемента выделяются рамкой красного цвета, чтобы сделать эффект более заметным. Страница в окне браузера показана на рисунке:

Если замена элемента нежелательна, можете просто вернуть его клон. Если не клонировать элемент, то jQuery полностью удалит его из документа. Конечно, этой проблемы можно избежать путем усечения выбранного набора, но такая возможность не всегда имеется.

Удаление элементов

В дополнение к возможности вставки и замены элементов библиотека jQuery предлагает ряд методов для удаления элементов из DOM. Краткое описание этой группы методов приведено в таблице ниже:

Пример использования метода remove() для удаления элементов приведен ниже:

$(function() { $("img, img").parent().remove(); });

В этом сценарии мы выбираем элементы img, атрибуты src которых содержат daffodil и snow, получаем их родительские элементы, а затем удаляем их. Можно также отфильтровать удаляемые элементы, передав селектор методу remove():

$(function() { $("div.dcell").remove(":has(img, img)"); });

Оба сценария приводят к одному и тому же результату:

Как показывает мой опыт работы с методом remove(), не все селекторы способны выполнять функцию фильтра. Я рекомендую тщательно тестировать каждый шаг и отдавать предпочтение исходному набору выбранных элементов, если только это возможно.

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

Метод detach() работает аналогично методу remove() с тем лишь отличием, что связанные с удаляемыми элементами данные сохраняются. О связывании данных с элементами подробно говорится в одной из следующих статей, а на данном этапе вам достаточно знать лишь то, что если планируется последующая вставка удаленных элементов в другое место документа, то обычно предпочтение следует отдавать методу detach().

Пример использования метода detach() приведен ниже:

$(function() { $("#row2").append($("img").parent().detach()); });

В этом сценарии удаляется родительский элемент элемента img, атрибут src которого содержит astor. Затем элементы вновь вставляются в документ с помощью рассмотренного нами ранее метода append(). Я стараюсь избегать такого подхода, поскольку использование метода append() без вызова метода detach() дает тот же эффект.

Приветствую всех.

jBone - микро библиотека (2кб gzipped) для работы с DOM в современных браузерах. Она частично имплементирует интерфейсы jQuery для основных методов необходимых для корректной работы Backbone, но может использоваться и независимо.

Проблема jBone родился при решении конкретной задачи - разработки мобильного приложения. Основными требованиями были отзывчивость UI и скорость загрузки приложения. Очень скоро стало ясно, что почти половину всего кода у нас занимает jQuery, причем решались с помощью него очень простые задачи.

Было принято решение отказаться от jQuery. Я действительно люблю его, за интуитивно понятные интерфейсы и кроссбраузерность. Интерфейсы хотелось бы оставить, но полная кроссбраузреность была не нужна, и я знал, что для имплементации подобной функциональности нужно намного меньше кода. К тому же можно получить хороший скачек в производительности используя современные возможности браузера вместо методов jQuery.Поиски решения Анализ показал, что есть уже готовые инструменты для решений этой задачи, но все они имеют недостатки. В начале я решил посмотреть на Zepto , около 30 кб, не так уж и мало, хоть и значительно меньше чем jQuery, к тому же он имеет существенные проблемы с производительностью проигрывая по перформансу в разы даже jQuery. Следующим шагом я попробовал собрать «свой jQuery» с помощью Ender , но полученный размер файла не вписывался в рамки моих ожиданий. Третьей попыткой стало желание получить Backbone без дополнительных библиотек для работы с DOM. Первым я нашел Backbone.Native . Идея неплохая, но отказываться от удобных алиасов мне кажется неразумно, количество кода будет расти намного быстрее, и процесс написания кода будет не столь удобен. Намного интереснее выглядит этот пулл реквест , идея в том, чтобы сделать jQuery опциональным для тех, кому он нужен, для остальных есть возможность использовать нативные методы, как в Backbone.Native, но проблема удобства и скорости разработки остается.

Сжав зубы, я решил написать свой велосипед. Я поставил перед собой цель уложиться в один день. Прототип должен был обеспечить минимальную совместимость с jQuery и проходить все unit тесты для Backbone, больше времени тратить не хотел принципиально, это означало бы, что в итоге мы придем к тому же с чего начали, к jQuery.

Решение Сейчас jBone это примерно 10кб несжатого кода, полностью покрытого тестами и обеспечивающий замену jQuery для Backbone.

Поговорим немного о реализации и отличиях от jQuery.

Selector engine Это простой querySelector , с его преимуществами и недостатками , во первых это не sizzle и не ждите от него полной совместимости с ним. Зато он быстрый, очень быстрый по сравнению с jQuery.Events Главное отличие в том, что вам придется работать с нативными событиями джаваскрипта, и это хорошо. Дело в том, что в jQuery почти полностью переписаны события. Например если добавить на элемент слушатель с помощью метода addEventListener , то событие не будет «всплывать», если нода не находится внутри документа, jQuery же решает эту «проблему», думаю из за этой «фичи» и вопросов обратной совместимостью, им еще очень долго не удастся перейти к полностью нативным эвентам. У jQuery есть свой объект Event, который имеет набор свойств отличный от стандартного, и так далее. Это все мелочи, но их нужно держать в голове.CSS В jBone метод css принимает свойства в camelCase стиле, то есть вместо border-color нужно писать borderColor .Атрибуты, Анимации Для работы с атрибутами в jBone нет практически ничего, потому что все что нужно есть в JavaScript.

Работа с атрибутами element.
Работа с классами element.classList.add
Работа с data-атрибутами element.dataset

То же самое касается и анимаций, я считаю, что настало то время когда в очень многих задачах мы можем отказаться от анимаций на стороне JS и полностью отдать их в руки CSS, отделив логику приложения от представления.

AJAX, Deferred Эта часть в библиотеке не покрыта совсем и оставлено право выбора. Реализаций AJAX"a есть

Можно заменить один набор элементов другим, используя методы, описанные в .

Таблица 7-5: Методы для замены элементов

Методы replaceWith и replaceAll работают одинаковым образом, за исключением того, что роли объекта jQuery и аргумента меняются местами. В представлены оба метода.

Листинг 7-19: Использование методов replaceWith и replaceAll $(document).ready(function () { var newElems = $("") .append("") .append("Orchid:") .append("") .css("border", "thick solid red"); $("#row1").children().first().replaceWith(newElems); $("").replaceAll("#row2 img") .css("border", "thick solid red"); });

В этом скрипте я использую метод replaceWith , что заменить первый дочерний элемент в row1 div новым контеном (результатом этого является замена астры на орхидею). Я также использую метод replaceAll , чтобы заменить все элементы img , являющиеся потомками row2 , на рисунок гвоздики. Результат работы скрипта можно увидеть на .

Рисунок 7-14: Замена контекста при помощи методов replaceWith и replaceAll Замена элементов с использованием функции

Можно заменить элементы динамически, если методу replaceWith добавить функцию. Этой функции не передается ни один аргумент, но переменная this устанавливается для обрабатываемого элемента. В листинге 7-20 представлен пример.

Листинг 7-20: Замена элементов с использованием функции $(document).ready(function () { $("div.drow img").replaceWith(function () { if (this.src.indexOf("rose") > -1) { return $(" } else if (this.src.indexOf("peony") > -1) { return $("").css("border", "thick solid red"); } else { return $(this).clone(); } }); });

В этом скрипте я заменяю элементы img , основываясь на их src атрибуте. Если src атрибут содержит rose , тогда я заменяю элемент img другим, отображающим carnation.png . Если src атрибут содержит peony , тогда я заменяю элемент img другим, отображающим lily.png . У обоих замененных элементов есть красная рамка, чтобы была четко видна их позиция в документе.

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

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

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

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

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

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

Параграф с текстом

Другой параграф с текстом

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

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

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

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

Параграф с текстом

Другой параграф с текстом

Текстовый узел, как он есть

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

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

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

Параграф с текстом

Другой параграф с текстом

Текстовый узел, как он есть

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

Параграф с текстом

Удаление элемента без разрушения его данных: 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() .

< p.red { color: red; } $(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"); }

Параграф с текстом

Другой параграф с текстом

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

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

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

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

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

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

Параграф с текстом

Другой параграф с текстом

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

Параграф с текстом

Другой параграф с текстом

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

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

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

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

$(init); function init() { // Заменяем параграф в #myDiv1 новым параграфом $("#myDiv1>p").replaceWith("

Новый параграф с текстом

"); // Заменяем параграф в #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 ("

Текущее время: " + currentHours + ":" + currentMinutes + ":" + currentSeconds + "

"); } }

Параграф с текстом

Параграф с текстом

Параграф с текстом

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

Новый параграф с текстом

Текущее время: 13:52:17

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

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

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

$("#myDiv").replaceWith("

Здесь новый текст

"); $("

Здесь новый текст

").replaceAll("#myDiv");

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

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

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

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

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

Параграф с текстом

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

Параграф с текстом

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

// Перемещаем параграф из #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 сначала удалит контент из старого родителя, затем клонирует контент столько раз, сколько нужно и добавит клоны в каждый указанный родительский элемент. Например:

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

Параграф с текстом

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

Параграф с текстом

Параграф с текстом

Резюме

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