【问题标题】:JavaScript: option hiding code not working in some browsersJavaScript:选项隐藏代码在某些浏览器中不起作用
【发布时间】:2021-08-09 04:12:33
【问题描述】:

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

【问题讨论】:

  • 最可能的问题是,当单击 &lt;option&gt; 时,chrome 无法运行 onclick - 您是否尝试过 console.log 在 hide_options 函数中的运行?
  • change 处理程序添加到select,并重写您的函数以解决此问题

标签: javascript google-chrome firefox


【解决方案1】:

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

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

showing 对象只是配置应该显示的内容的好方法,因此您不需要 if/else if/else if 等 - 我发现这比无数 if else if`'s 更容易维护

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 data-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 BC 的硬编码逻辑 - 此代码,服务器代码可以发出它喜欢的任何内容,而 javascript 不会需要改变

【讨论】:

  • @dmd - 我早就知道这里的最小代码永远不会真正具有代表性......当然,你可以使用value="A" ...甚至不需要data-target ...但是为什么原始代码有target?我希望我在这里展示的是如何将它添加到可能已经有value 的现有 HTML 中,并且可能有 options 影响不同的 select 元素
  • @dMd - 你是对的 if (x) ... 应该是 if (x &amp;&amp; x[0])
  • 干得好,谢谢Bravo! (或者我应该说,太棒了,太棒了!?)我喜欢“展示”的对象。现在是坏消息,对不起!我猜现在说这是我原始代码的精简版本不是一个好时机,根据输入文件的不同,它可能有几十对
  • 我的 Perl 代码动态生成必要的
  • 因为您的脚本在加载 DOM 之前运行 - 要么将脚本移动到 body 的底部,要么将脚本包装在 document.addEventListener('DOMContentLoaded', () =&gt; { script here })
猜你喜欢
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
相关资源
最近更新 更多