2017-01-03 73 views
0

我可能丢失/做一些愚蠢的,但我似乎不能工作了这一点:奇怪的JavaScript循环行为的Jquery追加

这里的显示问题小提琴: https://jsfiddle.net/jhqjmcn4/1/

请注意,您需要打开控制台才能看到发生了什么。

基本上,在这个例子中,我有两个函数包含一个for循环,除了第二个包含JQuery附加外,它们是相同的。

该函数的目标是从一个字符串中获取html元素,该元素在第一个函数中工作正常,但不是第二个。

从控制台中可以看出,这会导致任何不是文本节点的内容被忽略,也不会被添加到列表中。在这种情况下,b和p标签不包含在内。

这里再次代码:

JS:

function parse_text(text) { 
    var div = document.createElement("DIV"); 
    div.innerHTML = text; 
    var elements = div.childNodes; 
    var container = jQuery("#container"); 
    var list = []; 
    for (var i = 0; i < elements.length; i++){ 
     var element = elements[i]; 
     list.push(element); 
     console.log("First", list); 
    } 
} 

function parse_text_two(text) { 
    var div = document.createElement("DIV"); 
    div.innerHTML = text; 
    var elements = div.childNodes; 
    var container = jQuery("#container2"); 
    var list = []; 
    for (var p = 0; p < elements.length; p++){ 
     var element = elements[p]; 
     list.push(element); 
     console.log("Second", list); 
     container.append(element); 
    } 
} 

var text = "Here is <b>some</b> text with <p>html</p> in it"; 

parse_text(text); 
parse_text_two(text); 

HTML(无关):

<div id="container"> 

</div> 
<div id="container2"> 

</div> 

在此先感谢。

+1

目的是什么? – Satpal

+1

这两种方法都正常工作......您面临的问题是什么? – Samir

+0

问题出在第二个函数中,当应用程序运行时,element.length包含5,但是对于每次迭代,这个长度会发生变化,并且element.length将变为3.这是因为container.append函数 –

回答

0

我想你需要有一个Array.prototype.filter()方法来获得html元素:

function parse_text_two(text) { 
 
    var div = document.createElement("DIV"); 
 
    div.innerHTML = text; 
 
    var elements = [].filter.call(div.childNodes, function(el) { 
 
    return el.nodeType !== 3; 
 
    }); 
 
    var container = jQuery("#container2"); 
 

 
    var list = []; 
 
    for (var p = 0; p < elements.length; p++) { 
 
    var element = elements[p]; 
 
    list.push(element); 
 
    console.log("Second", list); 
 
    container.append(element); 
 
    } 
 
} 
 

 
var text = "Here is <b>some</b> text with <p>html</p> in it"; 
 

 

 
parse_text_two(text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="container"> 
 
</div> 
 
<div id="container2"> 
 
</div>

+0

请您向我解释为什么会这样与我做这件事的方式相比有什么不同? –

+0

因为那是一个集合,一个像对象但不是实际数组的数组,如果你用前面的代码记录'elements',你会发现除了子节点之外还有别的东西。 – Jai

0

您可以点击这里更新的提琴jsfiddle.net/bharatsing/jhqjmcn4/3/

它返回相同的结果两种方法在控制台根据你的需要。

function parse_text_two(text) {  
    var div = document.createElement("DIV"); 
    div.innerHTML = text; 
    var elementsOrg = div.childNodes; 
    var elements = Array.prototype.slice.call(elementsOrg);; 
    var container = jQuery("#container2"); 
    var list = []; 
    for (var p = 0; p < elements.length; p++){ 
     var element = elements[p]; 
     list.push(element); 
     console.log("Second", list); 
     container.append(element); 
    } 
} 
-1

在每个环路评论此线container.append(元件)的第二功能;

0

我看到把一个调试点循环中的问题是这样的:

container.append(element);声明实际上是修改的元素数组,并删除该数组中的元素追加。这意味着,在该环为“P”的各个值的元件阵列是这样的:

p = 0 -> elements : [ text, b, text, p, text ] // text node at 0 picked 
p = 1 -> elements : [ b, text, p, text ] // text node at 1 picked 
p = 2 -> elements : [ text, p, text ] // text node at 2 picked 

这就是为什么循环只跑元件阵列的原始长度,而不是3次,即5.

这可能是因为jQuery将节点从原始位置移动到容器div。

您可以克隆元素节点,然后添加到container:

function parse_text_two(text) { 
    var div = document.createElement("DIV"), 
     p, 
     element, 
     elements, 
     container = jQuery("#container2"), 
     list = []; 

    div.innerHTML = text; 
    elements = div.childNodes; 

    for (p = 0; p < elements.length; p++){ 
     element = elements[p]; 
     list.push(element); 
     console.log("Second", list); 
     container.append($(element).clone()); 
    } 
} 

或者使用while循环在文卡塔斯的答案建议。无论如何,知道根本原因总是更好。:)

希望这会有所帮助。