首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >避免双重循环来插入节点并激活它们?

避免双重循环来插入节点并激活它们?
EN

Stack Overflow用户
提问于 2014-03-27 01:37:42
回答 3查看 56关注 0票数 0

我遇到的一个常见问题是,需要在循环中创建多个DOM节点,然后以某种方式激活这些节点,无论是通过应用插件、事件处理程序还是类似的方式。激活步骤要求元素首先实际存在。

所以你最终会做一些类似这样的事情:

代码语言:javascript
运行
复制
// Loop 1: Create the nodes
var HTML = '<tr id="UID">';
for(var k in Fields){ // Fields is an object!
  HTML += '<td>';
  HTML += '<input class="ActivateMe"/>';
  HTML += '</td>';
}
var HTML += '</tr>';
$TableBody.children('tr').first().before(HTML);


// Loop 2: Activate the new nodes
$('#'+UID).children('td').children('.ActivateMe').each(function(index){
  $(this).InitSomePlugin();
});

上面的代码针对这个问题进行了简化,但假设给定单元格中的每个元素都可以是不同的(可能是输入,可能是div),也可能需要不同的插件(可能是颜色选择器,也可能是组合框)。

是否有可能避免在数据集上循环两次,并一次性执行插入和激活?我认为可以通过在第一个循环中添加节点来实现,这也允许在第一个循环中激活。但是它通常被认为是不好的做法,使用append在一个循环中,而不是存储您的所有HTML它在一个变量中,并附加所有的HTML一次。同时,对同一组数据循环两次似乎也很低效。在对性能影响最小的情况下处理此场景的最佳方法是什么?

EN

回答 3

Stack Overflow用户

发布于 2014-03-27 01:54:05

是。不要构建冗长的HTML字符串,而是在第一个循环中以编程方式创建元素,这样您就可以直接在它们上实例化您的插件:

代码语言:javascript
运行
复制
var $TableBody = …,
var $row = $('<tr>', {id:UID});
for(var k in Fields) { // sure that Fields is an object?
                       // For an array, use a normal for loop
  var $cell = $('<td>');
  var $input = $('<input class="ActivateMe"/>');
  $input.InitSomePlugin();
  $input.appendTo($cell);
  $cell.appendTo($row);
}
$row.prependTo($TableBody);

在调用.InitSomePlugin()之前,您可能需要执行追加操作。您可能还想嵌套调用,并使用链接来缩短代码:

代码语言:javascript
运行
复制
var $row = $('<tr>', {id:UID}).prependTo(…);
for(var k in Fields)
  $('<input class="ActivateMe"/>')
    .appendTo($('<td>').appendTo($row))
    .InitSomePlugin();
票数 2
EN

Stack Overflow用户

发布于 2014-03-27 02:07:16

由于激活步骤要求元素已经存在并且(可能)在DOM中,因此您在这里只有两个选择:

1)您可以单独创建每个DOM元素(使用document.creatElement()或jQuery的$(html)),这样您就保存了DOM对象引用,以便稍后用于初始化插件。

2)你可以像现在这样构建一个HTML字符串。插入该字符串,让浏览器为您创建所有元素,然后您必须找到适当的DOM元素才能初始化插件。

测试表明,通常情况下,与手动创建和插入单个DOM对象相比,当给定HTML字符串时,浏览器可以更快地创建大量HTML对象,因此使用HTML字符串没有什么特别的问题。

这里没有100%正确或错误的答案。性能可能不是主要问题,除非您有成百上千个这样的DOM元素。我倾向于选择通向最干净、最简单的代码的路径。

在本例中,您必须遍历Fields对象,因此无法避免这种情况。您必须找到表的第一行,因此无法避免。

如果您已经决定构建HTML字符串是编写代码的最方便的方法(这里可能就是这样),那么您无法避免在DOM中重新查找需要激活的对象。

你可以尽可能高效地处理事情。

这里有一些符合基本原理的精简:

代码语言:javascript
运行
复制
// create the new rows
var HTML = '<tr id="UID">';
for(var k in Fields) {
    HTML += '<td>' + '<input class="ActivateMe"/>'+ '</td>';
}
HTML += '</tr>';

// create an insert new content, save reference to new content
var newObj = $(HTML);
$TableBody.prepend(newObj);

// now activate the plugin on the appropriate objects in the new content
newObj.find(".ActivateMe").InitSomePlugin();

简化步骤:

  1. 在一条语句中创建每个单元格,而不是三个

代码当您创建新的row对象时,请保留对它的引用,这样我们就不必再次查找它。

  1. 当您添加新内容时,使用.prepend()使其成为第一行,而不是查找所有行并选择第一行
  2. 初始化插件,如果您在每个对象上运行相同的jQuery方法,则不需要.each()循环。你可以这样做:没有.each().

newObj.find(".ActivateMe").InitSomePlugin();

您还可以自己创建DOM对象,而不使用HTML字符串,并跟踪需要在执行过程中激活的对象,这样就不必再次找到它们:

代码语言:javascript
运行
复制
// create the new rows
var row = $('<tr id="UID"></tr>'), input, item, activates = [];
for(var k in Fields) {
    item = $('<td>');
    input = $('<input class="ActivateMe"/>')
    activates.push(input);
    item.append(input);
    row.append(item);
}

// insert row into table
$TableBody.prepend(row);

// now activate the plugin on the appropriate objects that are now inserted
$(activates).InitSomePlugin();

纯粹主义者可能比第一个选项更“喜欢”第二个选项,因为它不使用HTML字符串,但除非您在数百到数千次这样做,性能是最重要的(在这种情况下,您必须测试哪个方法实际执行得更好并诊断原因),否则我不能诚实地说第二个方法比第一个更好。我喜欢第一种方法的编码简单性,并且在特定表中找到几个类对象并不是一项昂贵的操作。

票数 -1
EN

Stack Overflow用户

发布于 2014-03-27 02:09:35

代码语言:javascript
运行
复制
$tableBody = $('table');

// Prepare an DOM object but don't append it to DOM yet.
$tr = $('<tr></tr>',{
    id: "UID"
});

// Loop over any condition you would see fit.
for(var i = 0; i < 2; ++i) {
    $td = $('<td></td>',{
        // Prepare your input element with your event bound to it
        "html": $('<input/>', {"class": "ActivateMe"}).InitSomePlugin();
    });
    // append your td element
    $tr.append($td);
}

// Add your tr element to the beginning of your table with prepand method.
$tableBody.prepend($tr);
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22668900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档