Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 避免双循环以插入节点并激活它们?_Javascript_Jquery - Fatal编程技术网

Javascript 避免双循环以插入节点并激活它们?

Javascript 避免双循环以插入节点并激活它们?,javascript,jquery,Javascript,Jquery,我遇到的一个常见问题是需要在一个循环中创建多个DOM节点,然后通过应用插件、事件处理程序或类似方法以某种方式激活这些节点。激活步骤要求元素首先实际存在 所以你最终会做一些类似的事情: // Loop 1: Create the nodes var HTML = '<tr id="UID">'; for(var k in Fields){ // Fields is an object! HTML += '<td>'; HTML += '<input class

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

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

// 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();
});
//循环1:创建节点
var HTML='';
对于(vark in Fields){//Fields是一个对象!
HTML+='';
HTML+='';
HTML+='';
}
var HTML+='';
$TableBody.children('tr').first().before(HTML);
//循环2:激活新节点
$('#'+UID).子项('td')。子项('ActivateMe')。每个(函数(索引){
$(this.InitSomePlugin();
});
上面的代码对问题进行了简化,但假设给定单元格中的每个元素都可能不同(可能是一个输入,可能是一个div),也可能需要不同的插件(可能是一个颜色选择器,可能是一个组合框)


是否可以避免在数据集上循环两次,一次插入并激活?我认为在第一个循环中添加节点是可能的,这也允许在第一个循环中激活。但通常认为在循环中使用append而不是将所有HTML存储在var中并一次追加所有HTML是不好的做法。与此同时,在同一组数据上循环两次似乎效率也很低。以最小的性能影响处理此情况的最佳方法是什么?

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

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

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

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

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

测试表明,通常情况下,浏览器在给定HTML字符串时会更快地创建大量HTML对象,而不是手动创建和插入单个DOM对象,因此使用HTML字符串没有特别的问题

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

在您的例子中,您必须迭代Fields对象,因此无法避免这种情况。你必须找到你桌子的第一行,这样你就无法避免了

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

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

这里有一些与基本理念保持一致的精简:

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

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

$tableBody=$('table');
$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);
//准备DOM对象,但不要将其附加到DOM中。 $tr=$(''){ id:“UID” }); //在任何你认为合适的条件下循环。 对于(变量i=0;i<2;++i){ $td=$(''){ //准备与事件绑定的输入元素 “html”:$('',{”类“:“ActivateMe”}).InitSomePlugin(); }); //附加您的td元素 $tr.append($td); } //使用prepand方法将tr元素添加到表的开头。 $tableBody.prepend($tr);
是的。打字速度比我快。:)字段是一个对象。我知道我可以在第一个循环中进行追加,但由于在循环中多次追加要比在循环中生成文本并立即追加慢,所以问题实际上是一个循环与另一个循环的性能影响,或者如果有第三种选择,你确定你能在元素插入DOM之前激活它吗?有些插件不能那样工作。@Nick:谁说速度慢了?
.appendTo($TableBody)最后只执行一次,因此没有不必要的更新。另外,为了在脚本中进一步使用元素(
.initSomePlugin()
),这只是一种方法,标记字符串在那里根本不实用。@jfriend00:检查我的嵌套:
var x=$(“Fee”).appendTo($((“Foo”).appendTo(“#test”)工作。您先将
费用
附加到
foo
,然后再附加到
test
,如果它结束了。请注意,我在对象键周围加了引号,以防止IE问题。以及IE在通过jQuery创建DOM对象时需要结束标记的“”和“”,我不认为您可以使用jQuery集合调用
$(“”)
是完全有效的,因为它不解析它,而是转换为
$(document.createElement(“tr”)
,您是对的,它在性能上几乎不重要。但是我更喜欢第二个选项的编码简单性和纯度:-)@Bergi-我喜欢HTML字符串的简单性,当然第一个选项的编码逻辑更简单。正如我所建议的,OP应该选择他们认为是最干净和最简单的代码的选项,我们展示的代码是个人意见
// 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();
$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);