javascript - 排序下拉列表

标签 javascript html html-select

我正在尝试对 html 中的下拉列表(选择器)进行排序。

我有两个列表,一个预选,然后应该用于定义第二个列表的内容。

简短的代码示例:

<!doctype html>
<html class="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body>
<table width=100% border="0">
  <tr>
  <td>&nbsp;</td>
    <td>Product</td>
    <td><select name="product" id="product" width="300" style="width: 300px">
      <option></option>
      <option id="TLX">TLX</option>
      <option id="FLX">FLX</option>
      <option id="MLX">MLX</option>
    </select></td>
    <td>&nbsp;</td>
  </tr>
  <tr>
  <td>&nbsp;</td>
    <td>Power</td>
    <td><select name="power" id="power" width="300" style="width: 300px">
      <option></option>
      <option name="TLX">6</option>
      <option name="TLX">8</option>
      <option name="TLX">10</option>
      <option name="TLX">12</option>
      <option name="TLX">15</option>
      <option name="FLX">6</option>
      <option name="FLX">8</option>
      <option name="FLX">10</option>
      <option name="FLX">12</option>
      <option name="FLX">15</option>
      <option name="FLX">17</option>
      <option name="MLX">30</option>
      <option name="MLX">40</option>
      <option name="MLX">60</option>
    </select></td>
    <td>&nbsp;</td>
  </tr>
</table>

</body>
</html>

我希望能够选择产品,然后必须相应地对电源列表进行排序。

例如,如果选择 TLX,则第二个列表中仅显示 6、8、10、12 和 15 作为可能性。

最佳答案

这里没有尝试跨浏览器......但我能想到的只有一种浏览器可能会给你带来麻烦:)

Demo

代码

var product = document.getElementById('product');
var power   = document.getElementById('power');
var allOpts = power.getElementsByTagName('option');
var opts = {
    empty: allOpts[0]
};

// This builds three additional lists of options for each type of product
// It relies on having a single attribute - if more are added, this logic
// would need to be adjusted.
for(var i = 1; i < allOpts.length; ++i) {
    var name = allOpts[i].attributes[0].value;

    opts[name] = opts[name] || [];
    opts[name].push(allOpts[i]);
}

// Each time product is changed, just loop through based on the selected ID
// and add those options to the power select list (removing all children first)
product.addEventListener('change', function(evt) {
    var val = evt.target.value;

    power.innerHTML = '';
    power.appendChild(opts.empty);
    for(var i = 0; i < opts[val].length; ++i) {
        power.appendChild(opts[val][i]);
    }
});

这是使用 documentFragment 的版本:

Demo

documentFragment版本

var product = document.getElementById('product');
var power   = document.getElementById('power');
var allOpts = power.getElementsByTagName('option');
var opts = {
    empty: allOpts[0]
};

// Appending to the doc fragment removes it from the live nodelist
while(allOpts.length > 1) {
    var name = allOpts[1].attributes[0].value;

    opts[name] = opts[name] || document.createDocumentFragment();
    opts[name].appendChild(allOpts[1]);
}

product.addEventListener('change', function(evt) {
    var val = evt.target.value;

    power.innerHTML = '';
    power.appendChild(opts.empty);
    power.appendChild(opts[val].cloneNode(true));
});

更新

只需多做一点工作,就可以变得更加通用 - 例如,当新需求出现在对原始答案的注释中时:)

其他要求

注意:我添加了空选项元素以使解决方案更简单。代码也可以调整以处理缺少它的情况,但这将留给读者作为练习。

<select name="continent" id="continent">'
    <option value="IMAGES/maps/europe_gray.png" id="EU">Europe</option>
    <option value="IMAGES/maps/europe_gray.png" id="AS">Asia</option>
</select>
<select name="country" id="country">
    <option></option>
    <option name="EU" id="ALB" value="IMAGES/flags/al.png">Albania, Republic of</option>
    <option name="AS" id="RUS" value="IMAGES/flags/ru.png">Russia</option>
</select>

通过以下更改, Controller 逻辑现在更加通用,因为它可以通过接受告诉它在哪里找到其键和选择元素的附加信息来适应标记。

Generic Controller Example

/* params {
 *    master: id of the master select element
 *    subord: id of the subordinate select element
 *    mKey:   name of the attribute holding the key in master that will be used to filter subordinate options
 *    sKey:   name of the attribute in subordinate that will be used to match against mKey
 */
function selectController(params) {
    var master = document.getElementById(params.master);
    var subord = document.getElementById(params.subord);
    var allOpts = subord.getElementsByTagName('option');
    var opts = {
        empty: allOpts[0]
    };

    // Appending to the doc fragment removes it from the live nodelist
    while (allOpts.length > 1) {
        var name = allOpts[1].getAttribute(params.sKey);

        opts[name] = opts[name] || document.createDocumentFragment();
        opts[name].appendChild(allOpts[1]);
    }

    master.addEventListener('change', function (evt) {
        var sel  = master.options[master.selectedIndex];
        var mKey = sel.getAttribute(params.mKey); 

        subord.innerHTML = '';
        subord.appendChild(opts.empty);
        subord.appendChild(opts[mKey].cloneNode(true));
    });
}

selectController({
    master: 'product',
    subord: 'power',
    mKey:   'id',
    sKey:   'name'
});

selectController({
    master: 'continent',
    subord: 'country',
    mKey:   'id',
    sKey:   'name'
});

关于javascript - 排序下拉列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18327985/

相关文章:

javascript - 如果通过 JavaScript 自动输入值,jQuery Validate 不会消除错误

html - 使用 border-radius 创建一个完全对称的圆而不指定高度或宽度

javascript - 将相同的元素 append 到两个下拉列表会导致仅 append 最后一个

html - 无法重置 CSS 外观属性

javascript - 如何使用 .on 在 jquery 中传递参数?

javascript - 创建接收包含属性 "props"的 "message"的 React 组件

javascript - 如何在调整窗口大小时禁用/重新启用 Javascript?

c# - 计算从日历中选择的 2 个日期之间的天数(C#)

javascript - 如果选择了选项,则运行 javascript 函数

javascript - 延迟加载功能坏了