【问题标题】:Work around for onclick event of option tag解决选项标签的 onclick 事件
【发布时间】:2013-11-22 07:49:42
【问题描述】:

我的网页上有一个多选下拉菜单和一个允许用户选择列表中所有项目的复选框。

<select id="itemsList" multiple="true" size="3"></select>
<input type="checkbox" id="bSelectAll" onclick="selectAllItems();" />Select all

单击复选框可选择列表中的所有项目。现在,当我单击列表中的一个项目时,该项目保持选中状态,而其他所有项目都被取消选择。我想要完全相反的行为。单击某个项目时,该项目应取消选择,而其他所有项目应保持选中状态。

我知道我们可以通过 ctrl+单击一个项目来获得这种行为。但是,要求是它应该在正常点击时发生。

我尝试检查选项标签的 onclick,但似乎它不符合标准,因此只有一部分浏览器支持。

我无法通过使用 select 标记的 onclick 和 onchange 事件来完成此操作。

未选中复选框时的行为应该是一致的。简而言之,单击选项标签应始终切换其选择。

如果我使用复选框列表而不是选择框,这将是默认行为。但是,到目前为止,有什么办法可以做到这一点吗?

【问题讨论】:

    标签: javascript html html-select


    【解决方案1】:

    一种方法是使用数组来记录选择/取消选择的内容,并在每次用户点击时重建您的选项。

    js:

    var record = [];
    
    var selectAllItems = function (target) {
        //toggle all options here and keep a record in "record" array ...
    }
    
    var doTheMagic = function(target){
        record[target.selectedIndex] = ! record[target.selectedIndex];
        rebuildOptions();
    
    }
    
    var rebuildOptions = function (){
        var itemsList = document.getElementById('itemsList');
        for (var i=0;i<record.length;i++){
                itemsList.options[i].selected = record[i];
        }
    
    }
    

    html:

    <select id="itemsList" multiple="true" size="3"  onclick="doTheMagic(this)">
        <option value="volvo">Volvo</option>
        <option value="saab">Saab</option>
        <option value="audi">Audi</option>
    </select>
    <input type="checkbox" id="bSelectAll" onclick="selectAllItems(this)" />Select all
    

    jsFiddle 演示:http://jsfiddle.net/3A9Xs/3/

    【讨论】:

    • 这是一个很好的解决方案,感谢您对此进行调查!但是,这在 IE(9) 中不起作用。正如我在问题中提到的,选项标签的 onclick 不适用于所有浏览器,这是您在解决方案中使用的。另一个小问题可能是 - 选项的重建在下拉列表中显示一些闪烁。也许我们可以接受它,但它必须适用于所有浏览器。
    • @Mandar 我已更新解决方案,改为在&lt;select&gt; 上收听onchange() 事件。希望它能在 IE(9) 中工作。是的,我注意到闪烁的问题,似乎没有办法首先阻止浏览器默认行为,希望其他人会知道解决方案。
    • 再次感谢您花时间更新解决方案!这现在在 IE 中有效。但是,您所做的更改带来了副作用。我选中全选复选框,然后继续一一取消选择项目,直到只剩下一个选定的项目。现在没有直接的方法来取消选择最后一个项目(取消选中复选框不起作用,因为在我们的页面中,一旦取消选中任何一个项目,我们就会取消选中它)或选择另一个项目而不是最后一个剩余项目。如果我决定采用你的解决方案,我必须先解决这个问题。
    • @Mandar 你是对的。再次修改解决方案。希望有效,
    • 我去看看。谢谢!
    【解决方案2】:

    这个 sn-p 使用 onclick,应该也适用于旧版 IE。

    在 IE 中,selectedIndex 始终返回第一个找到的 select 的选定索引,而不是用户选定的索引。一个修复方法是缓存select 的当前,它在函数的开头是实际选择的值。 IE 在迭代期间更改了该值,这就是需要缓存的原因。

    var select = document.getElementById('select'),
        toggle = document.getElementById('toggle'),
        options = select.options,
        selections = [],
        selectOption = function (e) {
            var n,
                target = e.target || e.srcElement,
                currentValue = target.value;
            for (n = 0; n < options.length; n++) {
                if (currentValue === options[n].value) { // or options[n].text, if values are not defined
                    selections[n] = !selections[n];
                }
                options[n].selected = selections[n];
            }
        },
        toggleAll = function () {
            var n, bool = this.checked;
            for (n = 0; n < options.length; n++) {
                options[n].selected = bool;
                selections[n] = bool;
            }
        },
        n;
    for (n = 0; n < options.length; n++) {
        selections.push(options[n].selected);
    }
    if (select.addEventListener) {
        select.addEventListener('click', selectOption);
        toggle.addEventListener('click', toggleAll);
    } else {
        select.attachEvent('onclick', selectOption);
        toggle.attachEvent('onclick', toggleAll);
    }
    

    A live demo at jsFiddle.

    【讨论】:

    • 看一看。谢谢!
    • 我最终用复选框列表替换了选择框。您的回答与 Ruocaled 的建议类似,但我接受了他的回答,因为他是第一个以很好的解决方法做出回应的人。如果 SO 允许我接受两个答案,我也会接受你的。谢谢!
    猜你喜欢
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多