回收DOM结构而不是重建它

时间:2017-10-02 04:39:14

标签: javascript jquery html css

我动态创建div,并希望通过检查div的id来以正确的顺序放置新的div。

创建新数据时,我对数组进行排序并创建一个新的div容器。在第一次构建DOM时,它工作正常,因为我首先创建数据然后为我的数组中的每个元素创建div容器。

通过单击按钮创建新容器时,数组将被排序,但新的div容器只是附加在其他容器之下。

每个div容器都有一个唯一的id,所以我可以通过检查它们的id来检查placemenet。

var myObjs = [];

function Obj(number, name) {
    this.number = number;
    this.name = name;
}

$(document).ready(function () {
myObjs.push(new Obj(4, "div # " + 4)); // create test data
myObjs.push(new Obj(15, "div # " + 15));
myObjs.push(new Obj(9, "div # " + 9));

myObjs = sortMyList(); // SORT

$(myObjs).each(function (index, current) {
buildContainer(current); // create the divs
});

createNewContainer(12); // create more test data by button click
createNewContainer(3); // create test data
});

function buildContainer(currentObj){ // Create a DOM element here
    var container = $("<div></div>");
  	container.addClass("singleContainer");
  	container.attr("id", currentObj.number);
    container.html(currentObj.name);
  	$("#listContainer").append(container);
}

function createNewContainer(newNumber){
	var newObj = new Obj(newNumber, "div # " + newNumber); 
  myObjs.push(newObj);
  
  myObjs = sortMyList(); // SORT
  
  buildContainer(newObj);
}

function sortMyList() {
    return myObjs.sort(function (a, b) {
        var key = "number";
        var x = a[key];
        var y = b[key];
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}
.singleContainer{
  height: 50px;
  background: red;
  color: white;
  margin-top: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="listContainer">

</div>

正如您所看到的,我需要修复buildContainer()函数来实现此目的。新创建的容器只需要知道将自己放在其他现有容器之间的位置。

我唯一的想法是摧毁所有容器并重新重建它们。但由于表现,我不想要这个,对吗?

所以我可以使用这段代码,我必须在排序数组后立即将它放入我的createNewContainer()函数。

  $("#listContainer").empty(); // Remove all children / div containers
  $(myObjs).each(function (index, current) {
    buildContainer(current); // build them all again
  });

一些帮助会很棒!

2 个答案:

答案 0 :(得分:1)

考虑到当前div已经在DOM中按顺序排列,一个选项是选择所有当前容器并创建一个循环以找到正确的位置......

var newId = 10;
var pos = 0;

$('div.singleContainer').each(function() {
    if (newId < $(this).attr('id')) {
        pos = parseInt($(this).attr('id'));
        return false; // We have the position, we don't need to keep looping!
    }
});

if (pos > 0)
    $('div.singleContainer#'+pos).before('<div id="'+newId+'" class="singleContainer">div # '+newId+'</div>');
else
    $('div#listContainer').append('<div id="'+newId+'" class="singleContainer">div # '+newId+'</div>');

注意:如果新id等于现有id,则会将新div置于现有ID之前。

所以,在你的情况下......

function buildContainer(currentObj) { // Create a DOM element here

    var pos = 0;

    $('div.singleContainer').each(function() {
        if (currentObj.number < $(this).attr('id')) {
            pos = parseInt($(this).attr('id'));
            return false; // We have the position, we don't need to keep looping!
        }
    });

    if (pos > 0)
        $('div.singleContainer#'+pos).before('<div id="'+currentObj.number+'" class="singleContainer">'+currentObj.name+'</div>');
    else
        $('div#listContainer').append('<div id="'+currentObj.number+'" class="singleContainer">'+currentObj.name+'</div>');
}

<强> EDITED

看看Martin Chaov的回答,他有一个好点。并且考虑到你有一组对象保持相同的顺序和元素,可能更好的选择是搜索该数组中的位置,而不是DOM元素。如果你有很多div,这个选项可能会更快......

function buildContainer(currentObj) { // Create a DOM element here

    var pos = 0;

    for (var i=0, l=myObjs.length; i<l; i++) {
        if (currentObj.number < myObjs[i].number) {
            pos = myObjs[i].number;
            break;
        }
    }

    if (pos > 0)
        $('div.singleContainer#'+pos).before('<div id="'+currentObj.number+'" class="singleContainer">'+currentObj.name+'</div>');
    else
        $('div#listContainer').append('<div id="'+currentObj.number+'" class="singleContainer">'+currentObj.name+'</div>');
}

我希望它有所帮助

答案 1 :(得分:1)

你应该有一个内存结构,它代表你正在使用的DOM,并且只与它交互。例如:

var struct = {};
struct["id" + number] = domRef

然后当你调用构建函数时,你会将引用传递给你想要放置它的对象:

buildContainer(newObj, struct["id" + number]);

您不需要循环查找所有内容,因为您在函数调用时传递了它。