2017-01-03 72 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循環在文卡塔斯的答案建議。無論如何,知道根本原因總是更好。:)

希望這會有所幫助。