jQuery插入div作为特定索引


78

说我有这个:

<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代码的简单动作非常恐怖,足以让我大喊大叫并拔掉头发,而我不想再花时间把它弄乱了!

Answers:


82

作为具有更好处理0的函数:

function insertAtIndex(i) {
    if(i === 0) {
     $("#controller").prepend("<div>okay things</div>");        
     return;
    }


    $("#controller > div:nth-child(" + (i) + ")").after("<div>great things</div>");
}

编辑:在第n个子选择器中添加了括号,以避免出现NaN错误。@hofnarwillie


2
您可能想使用.before(),而不是.append();)
Reigel 2010年

2
您应该使用,$("#controller > div:nth-child(" + i + ")").before("<div>great things</div>");因为否则,新元素可能会在#controller
squarebracket的子项中的子项中

1
对于第二个示例,这将以静默方式失败。位置2没有元素,因此也没有要插入的元素。由于您已经抓住位置0并单独处理,因此应该可以:$("#controller div:nth-child(" + i - 1 + ")").after("<div>great things</div>");
John H

3
不能eq(i)达到相同的目的nth-child(" + i - 1 + ")
MCB

1
需要转:nth-child(" + i - 1 + ")":nth-child(" + (i - 1) + ")"其他方式,否则您可能会遇到NaN问题。将修复程序添加到答案中。
hofnarwillie 2014年

55

我有一个类似的问题。不幸的是,没有一种解决方案对我有用。所以我这样编码:

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

以下是我的单元测试中的一些示例:

$("<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>");

编辑:它现在可以正常处理所有负片。


好方法!谢谢你 插上电源,就像魅力一样。
布拉德·高斯

1
var lastIndex = this.children()。size(); 不再工作-使用this.children()。length; 代替。
bibamann

8

我发现列出的解决方案不起作用或过于复杂。您所要做的就是确定要添加的方向。这是一种以OOP方式为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);

当前在可视化编辑器项目上使用此功能,通过拖放来移动大量数据。一切都很好。


编辑:我添加了一个实时交互式CodePen演示,您可以在其中使用上述解决方案http://codepen.io/ashblue/full/ktwbe


1
我喜欢您的解决方案的简单性Ash –做得很好。对我来说也很好。
Graham Ashton 2014年

我已经更新了上面的示例,其中包括CodePen演示codepen.io/ashblue/full/ktwbe
Ash Blue

这是否只是在不实际支持插入新元素的情况下交换元素?
DarkNeuron '16

@DarkNeuron您可以根据需要插入和移动任意数量的元素。查看CodePen的交互式演示。
Ash Blue

这更像是setIndex:它移动现有元素。这不是在特定索引处插入元素(例如,父级可能为空)。
NateS

6

使用我的简单插件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)

2
//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 );

0

如果您需要大量执行此操作,可以将其包装在一个小函数中:

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

如果您担心该临时ID,可以添加最后一步以将其删除。

编辑:更新为处理零个孩子的情况,并指定n >当前div数。


问题将是如果$('#controller')没有孩子,那么此功能将无法工作...addit(0)
Reigel 2010年

雷格尔,是的。为了娱乐,我真的很想尝试避免任何(本机)条件。这一更新的版本似乎适用于边境案件。
肯·雷德勒

0

这个最适合我

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

            }
        };

2
菲尔,能否请您详细说明一下您的答案?有时仅发布代码而无须说明,这进一步加剧了混乱。
Dwayne Charrington


-1

您可以始终使用prepend('#div');

例如

$(document).ready(function(){

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

});​

那会把“ #new”放在“ #first”之前。不确定那是不是您想要的。


3
这可以解决第0种情况。那第二个位置呢?他希望能够通过数字指定在div列表中插入div的位置
Tommy 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.