Javascript通过getElementbyId访问动态创建的元素

时间:2018-11-20 11:24:31

标签: javascript html dynamic

我将Javascript作为一种业余爱好,并且在访问通过其他功能动态创建的元素时遇到了麻烦。

从本质上讲,我有一个链接,该链接可以动态创建几个带有几个选项的下拉选择。然后,我有第二个链接,我将尝试将某些选定的选项打印到控制台上。

HTML:

<a href="#" id="make" onclick="maker()">create</a>
<a href="#" id="get" onclick="getter()">collect</a>
<div id="box"><br>

Javascript:

function maker() {
    box.appendChild(document.createElement("br"));
    for (i = 0; i < 2; i++) {
      box.appendChild(document.createTextNode("test " + (i + 1) + " "));
      for (k = 0; k < 2; k++) {
        var dropdown = document.createElement("select");
        box.appendChild(dropdown);
        for (j = 0; j < nice.length; j++) {
          var option = document.createElement("option");
          option.value = nice[j];
          option.text = nice[j];
          option.id = 'option' + i + k;
          console.log(option.id)
          dropdown.appendChild(option);
        }
      }
      box.appendChild(document.createElement("br"));
    }
}

function getter() {
  var test = document.getElementById("option01");
  console.log(test.options[test.selectedIndex].value);
}

我已经打印了创建选项ID的控制台(打印此选项ID似乎没有问题),并通过appendChild将它们添加到DOM中。但是,使用我的第二个功能,尽管显式引用了ID,我仍无法检索选项的选定值。

我的猜测是,这与脚本加载的顺序有关。谁能帮助我了解发生了什么事?

附件是我的JSFiddle文件, http://jsfiddle.net/c8h6gx2d/1/

干杯

2 个答案:

答案 0 :(得分:3)

问题在于<option>嵌套在<select>内,而* <select> *则具有selectedIndex属性。因此,当test.options[test.selectedIndex].valuetest元素时,<option>将不起作用。尝试使用getElementById来获取<select>之一,然后访问其.value(这比检查selectedIndex麻烦):

var nice = [2, 3, 5];

function maker() {
  box.appendChild(document.createElement("br"));
  for (i = 0; i < 2; i++) {
    box.appendChild(document.createTextNode("test " + (i + 1) + " "));
    for (k = 0; k < 2; k++) {
      var dropdown = document.createElement("select");
      dropdown.id = 'select' + i;
      box.appendChild(dropdown);
      for (j = 0; j < nice.length; j++) {
        var option = document.createElement("option");
        option.value = nice[j];
        option.text = nice[j];
        dropdown.appendChild(option);
      }
    }
    box.appendChild(document.createElement("br"));
  }
}

function getter() {
  var test = document.getElementById("select0");
  console.log(test.value);
  // same as:
  // console.log(test.options[test.selectedIndex].value);
}
<a href="#" id="make" onclick="maker()">create</a>
<a href="#" id="get" onclick="getter()">collect</a>
<div id="box"><br>

还要注意,单个文档中的重复ID是无效的HTML ,因此,如果您多次调用maker,为了使HTML有效,您可能需要单独的计数器maker外部递增:

const makeCount = 0;
function maker() {
  // ...
      dropdown.id = 'select' + makeCount + '_' + i;
  // ...
  makeCount++;
}

(或者,完全避免使用ID,如果可能的话,数字ID索引是一种代码味道-请改用类)

答案 1 :(得分:1)

我们需要区分 option 元素和 select 元素。 select元素是大多数时间要与之交互的元素,而option元素只是select元素可能条目的集合。

您现在的代码会生成以下类型的元素:

<select>
    <option value="2" id="option00">2</option>
    <option value="3" id="option00">3</option>
    <option value="5" id="option00">5</option>
</select>

如您所见,所有选项都具有相同的ID-HTML文档中通常禁止使用该ID。您可能会考虑将ID指示器移动到select元素,这也使您可以访问选定选项的值。

这是经过修订的JS代码,其中包含在修订之前的注释:

var nice = [2, 3, 5];

  function maker() {
    box.appendChild(document.createElement("br"));
    for (i = 0; i < 2; i++) {
      box.appendChild(document.createTextNode("test " + (i + 1) + " "));
      for (k = 0; k < 2; k++) {
        var dropdown = document.createElement("select");
        # Giving the select item an ID instead of each option
        dropdown.id = 'select' + i + k;
        box.appendChild(dropdown);
        for (j = 0; j < nice.length; j++) {
          var option = document.createElement("option");
          option.value = nice[j];
          option.text = nice[j];
          option.id = 'option'
          console.log(option.id)
          dropdown.appendChild(option);
        }
      }
      box.appendChild(document.createElement("br"));
    }
  }

  function getter() {
    # Getting the select element instead of the option 
    var selectElement = document.getElementById("select00");

    # The value attribute of the select element is the value of the selected option
    console.log(selectElement.value);
  }