JavaScript: 选项隐藏代码在某些浏览器中不起作用

JavaScript: option hiding code not working in some browsers

我的 JavaScript 技能很基础,但是我写了 this 代码,您可以从左侧的下拉列表中 select (Select1) 一个仅显示指定的选项右侧下拉列表中的选项 (Select2),并隐藏其余选项。 我还把它放在代码笔 here 中,以防你想要 fiddle。 代码似乎在 Firefox 90.0.2 的上述两种环境中都有效,但它在这两种环境中都失败了,并且在 Chrome 92.0.4515.131.

中没有向控制台写入任何内容

为什么它在 Firefox 中工作但在Chrome(和其他)中不工作的任何想法以及我能做的是它在所有主要浏览器上工作。

我是 运行 Windows 10,如果可行的话,我想避免使用 iQuery,因为我还不想开始学习或使用它,因为我刚开始有了基础。

谢谢。

代码如下:

<!DOCTYPE html>
<html>
<head>
  <script>
    function hide_options(select_id,type)
    {
      //alert("hide_options(select_id="+select_id+", type="+type+")");
      console.log("hide_options(select_id="+select_id+", type="+type+")");
      var x = document.getElementById(select_id);
      for (i=1; i<x.options.length; i++)
      {
        x.options[i].style.display = "none";
      }
      x.options[0].selected = true;
      if (type == 'A')
      { unhide_options(select_id,"one","two") }
      if (type == 'B')
      { unhide_options(select_id,"two","three") }
      if (type == 'C')
      { unhide_options(select_id,"two") }
    }
   
    function unhide_options(select_id,...opts)
    {
      //alert("unhide_options(select_id="+select_id+"opts="+opts+")");
      console.log("unhide_options(select_id="+select_id+"opts="+opts+")");
      for (i=0; i<opts.length; i++)
      {
        document.getElementById(select_id+"_"+opts[i]).style.display = "";
      }
    }
  </script>
</head>
<body>
  <p>Selecting an option in the "Select1" dropdown should show only those options in the "Select2" dropdown.</p>
  <select name=select1>
    <option>Select1...</option>
    <option onclick="hide_options('field1','A')">Show options 1 + 2 only</option>
    <option onclick="hide_options('field1','B')">Show options 2 + 3 only</option>
    <option onclick="hide_options('field1','C')">Show option 2 only</option>
  </select>
    
  <select name=update_action id=field1>
    <option value=''>Select2...</option>
    <option value=one id=field1_one>One</option>
    <option value=two id=field1_two>Two</option>
    <option value=three id=field1_three>Three</option>
  </select>
</body>
</html>

也许 Chrome 不会在单击选项时发出事件 - 但是,您可以在 select

上使用 change 事件

我已经为选项使用了 data-* 属性,而且我还在一个循环中 show/hide

showing 对象只是配置应显示内容的一种很好的简单方法,因此您不需要 if/else if/else if 等 - 我发现这比无数 if 更容易维护否则如果

const selects = document.querySelectorAll('.filterer');
const showing = {
  A: ["one", "two"],
  B: ["two", "three"],
  C: ["two"]
};
selects.forEach(select => {
  select.addEventListener('change', function(e) {
    const {
      target,
      value
    } = this[this.selectedIndex].dataset;
    const show = showing[value] || [];
    const x = document.getElementById(target) || [];
    [...x]
    .slice(1)
      .forEach(option =>
        option.style.display = (show.length === 0 || show.includes(option.value)) ? '' : 'none'
      );
    if (x && x[0]) {
      x[0].selected = true;
    }
  });
});
<p>Selecting an option in the "Select1" dropdown should show only those options in the "Select2" dropdown.</p>
<select id="select1" name="select1" class="filterer">
  <option>Select1...</option>
  <option data-target='field1' data-value='A'>Show options 1 + 2 only</option>
  <option data-target='field1' data-value='B'>Show options 2 + 3 only</option>
  <option data-target='field1' data-value='C'>Show option 2 only</option>
</select>

<select name=update_action id=field1>
  <option value=''>Select2...</option>
  <option value=one id=field1_one>One</option>
  <option value=two id=field1_two>Two</option>
  <option value=three id=field1_three>Three</option>
</select>
<br/>
<hr/>
<select id="select2" name="select2" class="filterer">
  <option>Select1...</option>
  <option data-target='field2' data-value='A'>Show options 1 + 2 only</option>
  <option data-target='field2' data-value='B'>Show options 2 + 3 only</option>
  <option data-target='field2' data-value='C'>Show option 2 only</option>
</select>

<select name=update_action id=field2>
  <option value=''>Select2...</option>
  <option value=one id=field2_one>One</option>
  <option value=two id=field2_two>Two</option>
  <option value=three id=field2_three>Three</option>
</select>

另类。您在评论中提到选择和选项是在服务器代码

上动态创建的

以下将允许您执行此操作,并在给定当前选择的情况下指定可见选择,所有这些都在 option 数据值属性

javascript 这种方式不需要硬编码

const selects = document.querySelectorAll('.filterer');
selects.forEach(select => {
  select.addEventListener('change', function(e) {
    const { target, values } = this[this.selectedIndex].dataset;
    const show = values.split(',').map(s => s.trim());
    const x = document.getElementById(target) || [];
    [...x]
    .slice(1)
      .forEach(option =>
        option.style.display = (show.length === 0 || show.includes(option.value)) ? '' : 'none'
      );
    if (x && x[0]) {
      x[0].selected = true;
    }
  });
});
<p>Selecting an option in the "Select1" dropdown should show only those options in the "Select2" dropdown.</p>
<select id="select1" name="select1" class="filterer">
  <option>Select1...</option>
  <option data-target='field1' data-values='one, two'>Show options 1 + 2 only</option>
  <option data-target='field1' data-values='two, three'>Show options 2 + 3 only</option>
  <option data-target='field1' data-values='two'>Show option 2 only</option>
</select>

<select name='update_action' id='field1'>
  <option value=''>Select2...</option>
  <option value='one' id='field1_one'>One</option>
  <option value='two' id='field1_two'>Two</option>
  <option value='three' id='field1_three'>Three</option>
</select>
<br/>
<hr/>
<br/>
<select id="select2" name="select2" class="filterer">
  <option>Select1...</option>
  <option data-target='field2' data-values='apple,banana'>Apple and banana</option>
  <option data-target='field2' data-values='banana,pineapple'>Banana and pineapple</option>
  <option data-target='field2' data-values='pineapple'>Pineapple</option>
</select>

<select name='update_action' id='field2'>
  <option value=''>Select2...</option>
  <option value='pineapple' id='field2_one'>Pineapple</option>
  <option value='banana' id='field2_two'>Banana</option>
  <option value='apple' id='field2_three'>Apple</option>
</select>

当然,这可能需要更改服务器代码,但您的原始代码确实具有 A BC 的硬编码逻辑 - 此代码,服务器代码可以发出任何内容它喜欢并且 javascript 不需要更改