Используйте JQuery, чтобы обернуть несколько наборов элементов в Div - PullRequest
0 голосов
/ 07 декабря 2009

Я работаю над выпадающим меню и мне нужно изменить существующую HTML-разметку с помощью JQuery, чтобы она соответствовала дизайну.

Вот упрощенный пример: Оберните все "ul", которые содержат более одного "li" в div (в том же div, НЕ один div для каждого UL).

<ul>
    <li>foo</li>
</ul>
<ul>
    <li>foo</li>
    <li>foo</li>
</ul>
<ul>
    <li>foo</li>
    <li>foo</li>
</ul>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

<script>
my_selection = [];
i = 0;
// find all ul's that have more than one li
$("ul").each(function(){
    if($(this).find("li").length > 1){
        // add this to my_selection
        my_selection[i] = $(this);
        i++;
    } // if
}); // each

// wrap my_selection in div tags
$(my_selection).wrapAll(document.createElement("div"));
</script>

Приведенный выше код выдает эту ошибку firebug:

«Узел не может быть вставлен в указанную точку иерархии» код: «3»

Как я могу заставить это работать?

Ответы [ 6 ]

5 голосов
/ 07 декабря 2009

Это было бы намного чище:

$('ul:has(li)').wrap('<div></div>');

Во-первых, вам не нужно создавать узел, просто предоставьте строку переноса в jQuery. Во-вторых, используйте селектор :has в этом случае, чтобы сократить функциональность each в вашем примере. Наконец, (это будет зависеть от вашей предполагаемой функциональности) вы можете использовать wrap вместо wrapAll.

EDIT: Другой вариант - подойти к нему с другой стороны. Получите теги <li>, затем возьмите родителя <ul>:

$('li:not(:only-child)').parent().filter('ul').wrap('<div></div>');
1 голос
/ 08 декабря 2009

Это что-то вроде хака.

<script>
jQuery( function() {
    my_selection = [];

    i = 0;
    n = 0;
    jQuery( 'ul' ).each( function() {
        var ul = jQuery( this );
        if ( ul.children().length > 1 ) {
            my_selection[n++] = 'ul:eq(' + i + ')';
        }
        ++i;
    } );

    jQuery( my_selection.join( ',' ) ).wrapAll( document.createElement( 'div' ) );
} );
</script>
0 голосов
/ 08 декабря 2009

Это все отличные ответы. Но я заметил, что ваш скрипт не находится внутри $(document).ready(function(){...}), и вы, похоже, убедились, что эта ошибка все еще существует с другим кодом, который не был включен в функцию ready.

Я попытался и обнаружил, что код Уильяма сработал (+1 к нему), но из-за моего OCD я немного его почистил

$(document).ready(function(){
 my_selection = [];
 $('ul').each(function(i){
  if ($(this).find('li').length > 1 ){
   my_selection.push(['ul:eq(' + i + ')']);
  }
 });
 $( my_selection.join(',')).wrapAll('<div class="wrapper"></div>');
})
0 голосов
/ 07 декабря 2009

Я был немного занят, когда ответил на этот вопрос, извините за все проблемы. Это следующее решает проблему правильно.

<script type="text/javascript">
jQuery( function() {
    jQuery( 'ul' ).find( 'li:eq(1)' ).parent().wrapAll( '<div></div>' );
} );
</script>

Редактировать: Я изменил li: gt (0) на li: eq (1) , они оба работают, но один имеет больше смысла.

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

Редактировать: Похоже, если вы редактируете свое сообщение более 8 раз, оно становится интересным вики-сообщества.

0 голосов
/ 07 декабря 2009

Я не уверен, что jQuery может принимать массивы в качестве селекторов. В $(my_selection) my_selection - это не объект jQuery, а массив объектов. Вы можете сначала попытаться сгенерировать объекты jQuery, используя var my_selection = $(''); ... my_selection.add($(this));.

Кроме того, с помощью метода .wrapAll() вы можете просто использовать: .wrapAll('<div></div>');.

0 голосов
/ 07 декабря 2009

В вашем коде есть ошибка, пытающаяся обернуть ваш LI в DIV.

<script>
my_selection = [];
i = 0;
// find all ul's that have more than one li
$("ul").each(function() {
    var $ul = $(this);
    if ($ul.find("li").length > 1){
        // add this to my_selection
        my_selection[i] = $ul;
        i++;
    } // if
});

// wrap my_selection in div tags
$(my_selection).wrap(document.createElement("div"));
</script>
...