Используйте JQuery для переноса нескольких наборов элементов в Div
Я работаю над выпадающим меню и мне нужно изменить существующую 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 ответов
Это был бы более чистый подход:
$('ul:has(li)').wrap('<div></div>');
Во-первых, вам не нужно создавать узел, просто предоставьте строку переноса для jQuery. Во-вторых, используйте :has
Селектор в этом случае, чтобы сократить each
функциональность в вашем примере. Наконец, (это будет зависеть от вашей предполагаемой функциональности) вы можете использовать wrap
вместо wrapAll
,
РЕДАКТИРОВАТЬ: Другой вариант будет подходить к нему с другой стороны. Получить <li>
теги затем захватить <ul>
родитель:
$('li:not(:only-child)').parent().filter('ul').wrap('<div></div>');
Это немного взломать.
<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>
Я не уверен, что jQuery может принимать массивы в качестве селекторов. В $(my_selection)
my_selection - это не объект jQuery, а массив объектов. Вы можете сначала попытаться сгенерировать объекты jQuery, используя var my_selection = $(''); ... my_selection.add($(this));
,
Кроме того, с .wrapAll()
Метод, вы можете просто использовать: .wrapAll('<div></div>');
,
В вашем коде есть ошибка, пытающаяся обернуть вашу 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>
Я был немного занят, когда я ответил на этот вопрос, извините за все проблемы. Это следующее решает проблему правильно.
<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 раз, оно становится интересным.
Это все отличные ответы. Но я заметил, что ваш сценарий не находится внутри $(document).ready(function(){...})
и вы, похоже, убедились, что эта ошибка все еще существует с другим кодом, который не был включен в готовую функцию.
Я попробовал и обнаружил, что код Уильяма сработал (+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>');
})