jQuery вставить div в качестве определенного индекса
скажи, что у меня есть это:
<div id="controller">
<div id="first">1</div>
<div id="second>2</div>
</div>
но скажите, что я хотел вставить новый div произвольно на основе индекса, который я поставляю.
скажем, я дал индекс для вставки 0, результат должен быть:
<div id="controller">
<div id="new">new</div>
<div id="first">1</div>
<div id="second">2</div>
</div>
и если у меня есть индекс для вставки 2 результат будет.
<div id="controller">
<div id="first">1</div>
<div id="second">2</div>
<div id="new">new</div>
</div>
и если я дам индекс 1 результат будет:
<div id="controller">
<div id="first">1</div>
<div id="new">new</div>
<div id="second">2</div>
</div>
просто забываем, что последний пример-это формат. Простой акт копирования и вставки HTML-кода на этом сайт достаточно ужасен, чтобы заставить меня кричать и вытаскивать волосы, и я не хочу больше тратить время на это!
9 ответов:
как функция с немного лучшей обработкой 0:
function insertAtIndex(i) { if(i === 0) { $("#controller").prepend("<div>okay things</div>"); return; } $("#controller > div:nth-child(" + (i) + ")").after("<div>great things</div>"); }
EDIT: добавлена скобка в селекторе nth-child, чтобы избежать ошибок NaN. @hofnarwillie
function insertAtIndex(i) { if(i === 0) { $("#controller").prepend("<div>okay things</div>"); return; } $("#controller > div:nth-child(" + (i) + ")").after("<div>great things</div>"); } window.doInsert = function(){ insertAtIndex(2); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="controller"> <div>Item 1</div> <div>Item 2</div> <div>Item 4</div> <div>Item 5</div> </div> <button onclick="doInsert()">Insert "great things" at index 2.</button>
у меня была похожая проблема. К сожалению, ни одно из решений работал для меня. Поэтому я закодировал его так:
jQuery.fn.insertAt = function(index, element) { var lastIndex = this.children().size(); if (index < 0) { index = Math.max(0, lastIndex + 1 + index); } this.append(element); if (index < lastIndex) { this.children().eq(index).before(this.children().last()); } return this; }
примеры для задачи:
$("#controller").insertAt(0, "<div>first insert</div>"); $("#controller").insertAt(-1, "<div>append</div>"); $("#controller").insertAt(1, "<div>insert at second position</div>");
вот несколько примеров, взятых из моих unittests:
$("<ul/>").insertAt(0, "<li>0</li>"); $("<ul/>").insertAt(0, "<li>0</li>").insertAt(1, "<li>1</li>"); $("<ul/>").insertAt(-1, "<li>-1</li>"); $("<ul/>").insertAt(-1, "<li>-1</li>").insertAt(0, "<li>0</li>"); $("<ul/>").insertAt(0, "<li>0</li>").insertAt(-1, "<li>-1</li>"); $("<ul/>").insertAt(-1, "<li>-1</li>").insertAt(1, "<li>1</li>"); $("<ul/>").insertAt(-1, "<li>-1</li>").insertAt(99, "<li>99</li>"); $("<ul/>").insertAt(0, "<li>0</li>").insertAt(2, "<li>2</li>").insertAt(1, "<li>1</li>"); $("<ul/>").insertAt(0, "<li>0</li>").insertAt(1, "<li>1</li>").insertAt(-1, "<li>-1</li>"); $("<ul/>").insertAt(0, "<li>0</li>").insertAt(1, "<li>1</li>").insertAt(-2, "<li>-2</li>"); $("<ul/>").insertAt(0, "<li>0</li>").insertAt(1, "<li>1</li>").insertAt(-3, "<li>-3</li>"); $("<ul/>").insertAt(0, "<li>0</li>").insertAt(1, "<li>1</li>").insertAt(-99, "<li>-99</li>");
Edit: он обрабатывает все негативные indizes изящно сейчас.
используйте мой простой плагин
Append With Index
:$.fn.appendToWithIndex=function(to,index){ if(! to instanceof jQuery){ to=$(to); }; if(index===0){ $(this).prependTo(to) }else{ $(this).insertAfter(to.children().eq(index-1)); } };*
теперь :
$('<li>fgdf</li>').appendToWithIndex($('ul'),4)
или :
$('<li>fgdf</li>').appendToWithIndex('ul',0)
я обнаружил, что перечисленные решения не работают или были слишком сложными. Все, что вам нужно сделать, это определить направление, в котором вы добавляете. Вот что-то простое написано в ООП-манере для jQuery.
$.fn.insertIndex = function (i) { // The element we want to swap with var $target = this.parent().children().eq(i); // Determine the direction of the appended index so we know what side to place it on if (this.index() > i) { $target.before(this); } else { $target.after(this); } return this; };
Вы можете просто использовать выше с некоторым простым синтаксисом.
$('#myListItem').insertIndex(2);
В настоящее время это используется в проекте визуального редактора, перемещая тонны данных с помощью перетаскивания. Все работает отлично.
Edit: я добавил живой интерактивная демонстрация CodePen, где вы можете играть с вышеуказанным решением http://codepen.io/ashblue/full/ktwbe
//jQuery plugin insertAtIndex included at bottom of post //usage: $('#controller').insertAtIndex(index,'<div id="new">new</div>'); //original: <div id="controller"> <div id="first">1</div> <div id="second>2</div> </div> //example: use 0 or -int $('#controller').insertAtIndex(0,'<div id="new">new</div>'); <div id="controller"> <div id="new">new</div> <div id="first">1</div> <div id="second>2</div> </div> //example: insert at any index $('#controller').insertAtIndex(1,'<div id="new">new</div>'); <div id="controller"> <div id="first">1</div> <div id="new">new</div> <div id="second>2</div> </div> //example: handles out of range index by appending $('#controller').insertAtIndex(2,'<div id="new">new</div>'); <div id="controller"> <div id="first">1</div> <div id="second>2</div> <div id="new">new</div> </div> /**! * jQuery insertAtIndex * project-site: https://github.com/oberlinkwebdev/jQuery.insertAtIndex * @author: Jesse Oberlin * @version 1.0 * Copyright 2012, Jesse Oberlin * Dual licensed under the MIT or GPL Version 2 licenses. */ (function ($) { $.fn.insertAtIndex = function(index,selector){ var opts = $.extend({ index: 0, selector: '<div/>' }, {index: index, selector: selector}); return this.each(function() { var p = $(this); var i = ($.isNumeric(opts.index) ? parseInt(opts.index) : 0); if(i <= 0) p.prepend(opts.selector); else if( i > p.children().length-1 ) p.append(opts.selector); else p.children().eq(i).before(opts.selector); }); }; })( jQuery );
Если вам нужно сделать это много, вы можете обернуть его в небольшую функцию:
var addit = function(n){ $('#controller').append('<div id="temp">AAA</div>') .stop() .children('div:eq('+n+')') .before( $('#temp') ); } addit(2); // adds a new div at position 2 (zero-indexed) addit(10); // new div always last if n greater than number of divs addit(0); // new div is the only div if there are no child divs
если вас беспокоит этот временный идентификатор, вы можете добавить последний шаг для его удаления.
Edit: обновлено для обработки случаев нулевых детей и указано n > текущее количество дивов.
Это лучше всего работает для меня,
function SetElementIndex(element, index) { var Children = $(element).parent().children(); var target = Children[index]; if ($(element).index() > index) { if (target == null) { target = Children[0]; } if (target != element && target != null) { $(target).before(element); } } else { if (target == null) { target = Children[Children.length - 1]; } if (target != element && target != null) { $(target).after(element); } } };
использовать .insertAfter():
$('<div class="new">').insertAfter($('div.first'));