使用JavaScript

时间:2016-05-07 03:57:33

标签: javascript forms dom select

我有3列HTML选择字段,需要根据以前的选择字段加载otions。

第2列值中的选择将取决于第1列选择中的选定值。我在下面有这个原始JavaScript,它为HTML选择字段添加2个选择选项,然后根据选择1中的选择值删除2。

我的问题是删除2个选择字段选项的部分不会删除这两个选项,而是删除其中的1个选项。

演示:http://jsfiddle.net/jasondavis/croh2nj8/3/

我意识到其中一些使用jQuery,但目标是在没有jQuery的情况下使用原始JS来处理这个问题....

$(document).ready(function() {

  $("#action").change(function() {

    var el = $(this) ;
    var selectAttributeEl = document.getElementById('action-attribute');

    if(el.val() === "form" ) {
        var option = document.createElement('option');
        option.text = 'Name';
        var option2 = document.createElement('option');
        option2.text = 'ActionURL';
        selectAttributeEl.add(option);
        selectAttributeEl.add(option2);

    }else if(el.val() === "link" ) {
        for (var i=0; i<selectAttributeEl.length; i++){
          if (selectAttributeEl.options[i].value == 'Name'){
             selectAttributeEl.remove(i);
          }else if(selectAttributeEl.options[i].value == 'ActionURL'){
             selectAttributeEl.remove(i);
          }
        }
    }
  });

});

3 个答案:

答案 0 :(得分:2)

问题出在for循环中,您循环遍历selectobject.options。当第一个if条件为真时,您可以通过删除selectobject.options选项来改变Name。在循环的下一次迭代selectobject.options[i]现在返回undefined

让我们通过for循环演示:

  1. i为0,对应于选项ID,没有任何反应。
  2. i为1,对应于选项Class,没有任何反应。
  3. i为2,对应于选项Nameif语句有效,并删除Name选项。现在selectobject.options的{​​{1}}为3。
  4. length为3,对应i。也就是说,undefinedselectobject.options[3],因为循环的上一次迭代从undefined中删除了一个项目。
  5. 一个可能的解决方案,在selectobject.optionsif语句中,您可以使用else重置i一个。{1}}。这是updated jsFiddle。另一种选择是向后循环i--,因为变异后者的项目在移动到前一项时不会影响计数器。

    还有其他方法可以解决此问题,例如根据要保留在选项中的值创建新的selectobject.options数组,然后将新选项加载到options。< / p>

答案 1 :(得分:1)

我可以提出一个不同的方法吗?不要通过删除不应该存在的元素来维护菜单的状态,而是彻底清除菜单option标签并替换。

&#13;
&#13;
$(document).ready(function() {
  var options = {
      link: ['ID', 'Class']
    },
    dependentMenu = document.getElementById('action-attribute');

  options.form = options.link.concat(['Name', 'ActionURL']);

  $("#action").change(function() {

    var el = $(this);

    while (dependentMenu.firstChild) {
      dependentMenu.removeChild(dependentMenu.firstChild);
    }

    options[el.val()].forEach(function(value) {
      var option = document.createElement('option');
      option.text = value;
      dependentMenu.add(option);
    });

  });

});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
When :
<select id="action" name="action">
  <option value="link">Link Clicked</option>
  <option value="form">Form Submitted</option>
</select>

with:

<select id="action-attribute" name="action-attribute">
  <option>ID</option>
  <option>Class</option>
</select>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

正如我所说,你很简单地得到了这个问题,因为for循环是从索引0开始的,并且正在向上发展。删除元素后,将其从NodeList的{​​{1}}中删除。我知道的最简单的方法是从节点列表的末尾开始,然后按照节点编号0的方式工作。

&#13;
&#13;
options
&#13;
$(document).ready(function() {

  $("#action").change(function() {

    var el = $(this);

    if (el.val() === "form") {
      //$("#action-attribute").append('   <option value="Name">Name</option>');
      //$("#action-attribute").append('   <option value="ActionURL">ActionURL</option>');
      var x = document.getElementById('action-attribute');
      var option = document.createElement('option');
      option.text = 'Name';
      var option2 = document.createElement('option');
      option2.text = 'ActionURL';
      x.add(option);
      x.add(option2);

    } else if (el.val() === "link") {
      //$("#action-attribute option:last-child").remove() ; 
      var selectobject = document.getElementById("action-attribute");
      var remove_array = ['Name', 'ActionURL'];
      for (var i = selectobject.options.length - 1; i >= 0; i--) {
        if (remove_array.indexOf(selectobject.options[i].value) != -1) {
          selectobject.removeChild(selectobject.options[i]);
        }
      }
    }
  });

});
&#13;
&#13;
&#13;