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 64

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'));

вы всегда можете использовать prepend ('#div');

ex.

$(document).ready(function(){

$('#first').prepend('<div id="new">New</div>');

});​

что бы поставить " #new "перед" #first " не уверен, что это то, что вы хотите.