jQuery集合在每个循环中被破坏(删除elem,恢复innerHTML)

时间:2018-06-01 17:18:30

标签: javascript jquery html dom foreach

我希望以下代码迭代选择选项并删除具有特定值的选项,否则恢复选择html

var initialHTML = $('#myselect').html();

$('#myselect option').each(function(){
    if($(this).val() === 'b'){
        $(this).remove();
        console.log('matching. removed.');
        return false;
    }else{
        $('#myselect').html(initialHTML);
        console.log('not matching. html restored.');
    }
});

预期选择将是:

<select id="myselect">
    <option value="a">a</option>
    <option value="c">c</option>
</select>

但实际上是

<select id="myselect">
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
</select>

我做错了什么? FIDDLE

更新,例如有人建议:

  

$('#myselect option')构建选项列表,以及   $(this).remove()删除选项b,但选项列表为否   与HTML链接的时间更长,因为HTML已经更改   由$('#myselect').html(initialHTML)执行的选项   a

所以,我意识到实际问题甚至与我在问题中最初提出的问题无关。对不起,我会尝试把它放在正确的部分。

P.S。 工作解决方案

var initialHTML = $('#myselect').html();

function doIt(){
    $('#myselect').html(initialHTML);

    $('#myselect option').each(function(){
        if($(this).val() === 'b'){
            $(this).remove();
        }
    });
}

非常感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

主要问题是这一行:

$('#myselect').html(initialHTML);

对选项a执行,然后无法再删除选项b,因为HTML已更改,即使它实际上是相同的。所以删除那一行,你的代码就可以了。

$('#myselect option')构建了一个选项列表,$(this).remove()从列表中删除了选项b,但该列表不再与HTML相关联,因为HTML已经被更改了已为选项$('#myselect').html(initialHTML)执行的a

&#13;
&#13;
var initialHTML = $('#myselect').html();

$('#myselect option').each(function() {
  if (this.value === 'b') {
    $(this).remove();
    console.log('matching. removed.');
    return false;
  } else {
    //$('#myselect').html(initialHTML);
    console.log('not matching. html restored.');
  }
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="myselect">
  <option>a</option>
  <option>b</option>
  <option>c</option>
</select>
&#13;
&#13;
&#13;

我将$(this).val()更改为this.value。两者都可以工作,但第二个更有效,因为将JavaScript对象转换为jQuery对象没有意义,只是为了获取值。

但是,请记住以下行:

return false;
一旦找到匹配项,

将导致each()循环退出。如果只有一场比赛,那没关系。如果可以有多个匹配,则删除该行,以便循环可以遍历所有选项。

答案 1 :(得分:3)

这是另一种方式:

其他答案已经指出了原因,因为您在第一次迭代期间刷新了选项列表,$(this).remove()不再有效,因为它失去了原始项目的联系。因此,这里的一个简单修复就是根据它的值重新选择目标。您可以将原始代码$('#myselect').html(initialHTML);保留在循环中。

var initialHTML = $('#myselect').html();
$('#myselect option').each(function(){
    if($(this).val() === 'b'){
        $("option[value='" + $(this).val() + "']").remove();
        console.log('matching. removed.');
        return false;
    } else { 
        $('#myselect').html(initialHTML);
        console.log('not matching. html restored.');
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="myselect">
    <option value='a'>a</option>
    <option value='b'>b</option>
    <option value='c'>c</option>
</select>

答案 2 :(得分:-1)

试试这个: 你不需要其他部分,因为它已经存在并将你的jquery放在document.ready中,这样它就能确保DOM准备就绪,你可以运行jquery脚本。

var initialHTML = $('#myselect').html();
   $(document).ready(function(){
     $('#myselect option').each(function(){
        if($(this).text() == 'b'){
            $(this).remove();
            console.log('matching. removed.');
            return false;
        }
    });
   });

JSFiddle

答案 3 :(得分:-2)

这里发生的事情是你有一些东西只需要一次就可以恢复整个选择。所以它确实删除了&#39;&#39;当它找到它时,但是一旦它看到“c&#39;”,它就会恢复整个选择。 !==&#39; b&#39;。

您可以通过删除以下内容来实现预期的行为:

else{
    $('#myselect').html(initialHTML);
    console.log('not matching. html restored.');
}

根据您的最终目标,可能有更好的方法来解决这个问题。

希望有所帮助。