2013-02-20 5 views
0
<div class="parent"> 
    <span>sometext</span> 
    plain text 
    <input class="child"> 
</div> 
<div class="parent"> 
    <span>sometext</span> 
    plain text 
    <input class="child"> 
</div> 
<div class="parent"> 
    <span>sometext</span> 
    plain text 
    <input class="child"> 
</div> 

Как безопасно удалить все фильтры в .parent За исключением .child?Удалить все, кроме детей

Я использую этот код (где items является стопка .child и each является .child)

items.each(function(){ 
    $(this).parent().children().each(function(){ 
     if ($(this).hasClass('child')) 
      // do something 
     else 
      $(this).remove(); 
    }); 

    $(this).unwrap(); // remove parent, keep only .child 
}); 

Но он не обрабатывает простой текст.

ответ

3

Вы сказали

Там может быть более чем один .child внутри .parent, мы держим только первый. Так что если есть три, второй и третий, нужно удалить.

и

items является стек .child и каждый из них является .child

Хорошо, тогда это то, что я хотел бы сделать:

items.parent('.parent').each(function() { 
    var parent = $(this), 
     child = parent.children('.child').first(); 
    child.detach(); 
    parent.empty().append(child); 
}); 

Что это .:

  1. Перемещение из набора .child элементов до набора .parent элементов. Результирующий набор будет иметь только уникальных родителей.

  2. Петли через родителей.

  3. Получает первый.child у каждого родителя и отделяет его.

  4. Опорожняет .parent.

  5. Повторно прикрепляет .child.

Конечный результат в том, что каждый .parent будет иметь только один .child (и не других детей, независимо от .child или нет).

+0

Начиная селектор всегда '$ (это)', который '.child', а не' .parent' – Jasper

+0

не уверен, как я могу использовать его внутри '$ (это)' – Jasper

+0

Если начальный селектор всегда ребенок, код может потенциально запускаться много раз. Есть ли способ сделать родительский стартовый селектор? –

1

Нечто подобное сделает это;

$('.parent').on('click', '.child', function(e) { 
    var $this = $(this), 
     $parent = $this.parent(), 
     $children = $parent.find('.child'); // or: $this.siblings('.child'); 

    $parent 
     .empty() // Empty the "parent" element 
     .append($children); // Re-append all "child" element to "parent" 
    $this.focus(); // Focus the (input) element 
}); 
+1

Багги, если есть несколько '.child'. –

+0

Хорошо, добавил '$ children'. – Stefan

2

Здесь вы бы решение с чистым JS: fiddle

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

this.parentNode.innerHTML = this.outerHTML; 

Если бы вы должны держать прикрепленные обработчики событий :

var _this = this.cloneNode(true), 
    parent = this.parentNode; 
parent.innerHTML = ''; 
parent.appendChild(_this); 
1

Вот альтернатива, используя регулярное выражение:

$('.parent').each(function() { 
    $(this).html($(this).html().match("<input class=.child.>")); 
}); 
+0

Это приведет к сбою * всех видов * содержимого (' Мой ребенок любит мороженое, например), и делает совершенно ненужную обратную маршрутизацию через разметку, тем самым теряя любые обработчики событий или такие приложенные для детей. –

+0

Исправлен код, но да, обработчики событий будут потеряны как это. –

+1

И вот Стив все знает, как он хочет начать с 'items', где' items' - это набор элементов '.child'. (Примерно половина ответа на мой ответ заключалась в том, что он не хотел делать простую вещь, которую я изначально предлагал, а также «$ («. Parent »). Каждый' как ваш, но без разметки в обе стороны.) –

Смежные вопросы