使用Jquery追加时,奇怪的Javascript for循环行为

时间:2017-01-03 07:15:59

标签: javascript jquery html

我可能错过了/做了些傻事,但我似乎无法解决这个问题:

这是一个显示问题的小提琴: 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>

提前致谢。

4 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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);
    }
}

答案 2 :(得分:0)

通过在循环中放置调试点我看到的问题是:

container.append(element);语句实际上是修改了elements数组,并从数组中删除了附加的元素。这意味着在循环中可以获得各种价值的&#39; p&#39; elements数组看起来像这样:

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&#39;移动&#39;节点从原始位置到容器div。

您可以克隆元素节点,然后追加到容器中:

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

或者按照Venkatesh的回答中的建议使用while循环。无论如何,了解根本原因总是更好。 :)

希望这有帮助。

答案 3 :(得分:-1)

在每个循环的第二个函数中注释此行container.append(element);