首页 > 解决方案 > JavaScript:选项隐藏代码在某些浏览器中不起作用

问题描述

我的 JavaScript 技能非常基础,但我编写了这段代码,您可以从左侧的下拉列表 (Select1) 中选择一个选项,该选项仅显示右侧下拉列表中的指定选项 (Select2),并隐藏其余选项。我也把它放在一个代码笔,以防你想摆弄。该代码似乎在 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>

标签: javascriptgoogle-chromefirefox

解决方案


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

我已经data-*为选项使用了属性,并且我还在一个循环中显示/隐藏

showing对象只是配置应该显示的内容的一种很好的简单方法,因此您不需要if/else if/else if等-我发现这更容易维护,然后无数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>

选择。您在评论中提到选择和选项是在服务器代码上动态创建的

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

这种方式不需要在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 B并且C- 此代码,服务器代码可以发出它喜欢的任何内容,并且不需要更改 javascript


推荐阅读