Jquery: клонирование внутри итерации (.each) шифрует структуру html

У меня есть фрагмент кода, который я не могу исправить. Все работает нормально, если я не перебираю функцию, или если я не клонирую. Когда я их соединяю, структура div'ов сбивается.

Перед любым кодом я начинаю с:

<div class="origin"></div>

Затем я пишу скрипт для добавления html, который должен иметь следующую структуру: Код:

<div id="id0">
  <div class="scroller">
    <div class="origin"></div>
  </div>
  <a href="#"></a>
</div>
<div class="viewport"></div>
<div id="id1">
  <div class="scroller">
    <div class="origin"></div>
  </div>
  <a href="#"></a>
</div>
<div class="viewport"></div>

Он начинается нормально, но если вы раскомментируете две строки ниже, второй div с идентификатором теперь находится внутри предыдущего окна просмотра, а не обернут вокруг «происхождения». Я пытаюсь скопировать изображения и, возможно, подписи внутри каждого «происхождения» внутри своего собственного окна просмотра (с двумя окружающими div на изображениях).

Код:

function writeGallery(i) {
    var startDiv = $("div.origin:eq("+i+")");
    startDiv.wrap('<div class="scroller"></div>');  
    startDiv.parent().wrap ('<div id="id' + i + '" />');
    var horizThumbwrap      = startDiv.parent().parent();
    horizThumbwrap.append ('<a href="#"></a>');
    horizThumbwrap.after ('<div class="viewport" />');

    //var horizViewport        = startDiv.parent().parent().next(".viewport");
    //startDiv.clone().appendTo(horizViewport);
}

$(document).ready(function(){

$("div.origin").each(function(index) {
writeGallery (index);
});

$('#result').text($('#container').html());
});

Код здесь в fiddle (раскомментируйте 2 строки, чтобы увидеть беспорядок): http://jsfiddle.net/AjSnx/< /а>

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

Кто-нибудь может помочь? Спасибо!


person Jennifer Michelle    schedule 14.07.2012    source источник
comment
вы добавляете клонированные данные в horizViewport, который не определен.   -  person undefined    schedule 14.07.2012
comment
Это работает в первой итерации — вы раскомментировали обе строки? Я не понимаю, как это может работать даже один раз, если оно не определено. Или ммм, я полагаю, что может, я недостаточно понимаю, чтобы знать.   -  person Jennifer Michelle    schedule 14.07.2012


Ответы (3)


Внутри каждого цикла вы выбираете элементы .origin, используя :eq(). Однако в каждом цикле вы создаете еще один <div class="origin" />. Итак, в следующем цикле вы выбираете <div>, который вы только что создали, используя .clone(), а а не <div>, который был там с самого начала. Чтобы исправить это, используйте второй аргумент, переданный функции, вызываемой .each(). Он содержит текущий элемент, который был сопоставлен в начале (то есть элемент, который вы намеревались использовать внутри цикла).

Подробнее см. мои обновления. Полученный HTML-код выглядит следующим образом:

<div id="id0">
    <div class="scroller">
        <div class="origin"></div>
    </div>
    <a href="#"></a>
</div>
<div class="viewport">
    <div class="origin"></div>
</div>

<div id="id1">
    <div class="scroller">
        <div class="origin"></div>
    </div>
    <a href="#"></a>
</div>
<div class="viewport">
    <div class="origin"></div>
</div>
person Wolfram    schedule 14.07.2012
comment
Ой! Я изучаю это, но похоже, что вы исправили это, большое спасибо. Теперь постараюсь понять. :) - person Jennifer Michelle; 14.07.2012
comment
Спасибо за это обновление Вольфрам. Это нубская ошибка, а? Я только что узнал много из этого, спасибо. :) - person Jennifer Michelle; 14.07.2012
comment
Только потому, что вы получаете этот элемент из jQuery, поэтому нет необходимости выбирать его снова. Хотя ловить довольно сложно. Вы также можете еще больше сократить свой код, см., например, ответ Раминсона. - person Wolfram; 14.07.2012

Если я не понял полностью наоборот, вы пытаетесь поместить содержимое origin-div в viewport-div, где origin — startDiv, верно?

Возможно, вам не нужно что-то клонировать, может быть, просто заполните innerHTML области просмотра с помощью innerHTML происхождения

startDiv.closest('.viewport').html( startDiv.html() );

Это работает для вас?

person mgherkins    schedule 14.07.2012
comment
Спасибо Макс, это полезная идея, чтобы сохранить. :) - person Jennifer Michelle; 14.07.2012

в качестве альтернативы вы можете попробовать это:

   $("div.origin").each(function(i) {
       $(this).wrap('<div id="id'+i+'><div class="scroller"></div></div>')
       $(this).after('<a href="#"></a><div class="viewport"></div>')     
   });

http://jsfiddle.net/AjSnx/3/

person undefined    schedule 14.07.2012
comment
Я не знал, что jQuery достаточно умен, чтобы обернуть дважды, хороший совет! - person Jennifer Michelle; 14.07.2012