在不使用 ctrl 键的情况下从 html select 元素中选择多个

IT技术 javascript jquery html
2021-02-23 17:15:54

我在网上遇到过针对这个问题的各种解决方案。

基本上,我发现必须按住 ctrl 有点俗气,我希望选择列表只选择我单击的任何内容并将其添加到当前选定的项目中。

我已经有了这个代码:

    $("select[multiple] option").mousedown(function () {
        var $self = $(this);            

        if ($self.attr("selected")) {                
            $self.removeAttr("selected", "");
        }
        else {
            $self.attr("selected", "selected");
        }

        return false;            
    });

元素:

    <select multiple id="WOStatusKey" name="WOStatusKey">                
        <option value="1">Created</option>
        <option value="2">In Process</option>
        <!-- etc. (about 20 of these) -->
    </select>

它工作正常,但有一个例外:任何时候选择/取消选择不在列表顶部(您必须滚动才能看到它)的内容,然后在您选择它后它会弹回到顶部。我已经玩了一点,但无法想出任何办法来防止这种行为。此外,我已经看到了解决这个问题的其他几个解决方案,尽管没有任何方法可以正常工作或运行良好。

我只需要它在 Chrome 中工作。此外,我对使用选择列表的任何替代解决方案都不感兴趣。

感谢您的任何帮助,非常感谢。

6个回答

您可以保存Element.scrollTop并将其设置在最后。

$("select").mousedown(function(e){
    e.preventDefault();

    var select = this;
    var scroll = select .scrollTop;

    e.target.selected = !e.target.selected;

    setTimeout(function(){select.scrollTop = scroll;}, 0);

    $(select ).focus();
}).mousemove(function(e){e.preventDefault()});

http://jsfiddle.net/UziTech/cjjg68dr/114/

我更新了小提琴以在 setTimeout 中设置 scrollTop 以便它会在事件循环结束时更新它
2021-04-25 17:15:54
谢谢你,先生!我从来没有找到解决办法。这很好用!
2021-05-11 17:15:54
这个小提琴在最新的 Chrome 中不起作用;如OP所述,如果您选择#2,然后向下滚动到#9,则选择框将在单击后立即再次自动滚动到#2。
2021-05-11 17:15:54
终于有一个有效的解决方案了!顺便说一句,在 Safari/Opera/Chrome/FF 上测试过,不适用于 FF
2021-05-15 17:15:54
如果您有阻止工作的onChange处理程序preventDefault(),只需添加$("#mySelect").trigger("change"). 您仍将获得 Ctrl+单击效果。
2021-05-16 17:15:54

托尼的回答使选择箭头有问题,因为它们只有在您按住鼠标时才起作用。

我已经结合了一些解决方案,它至少在 Chrome 和 FF 中运行良好:

// multiple select: selectable without Control
$('select[multiple] option').on('mousedown', function(e) {
    var $this = $(this),
        that = this,
        scroll = that.parentElement.scrollTop;

    e.preventDefault();
    $this.prop('selected', !$this.prop('selected'));

    setTimeout(function() {
        that.parentElement.scrollTop = scroll;
    }, 0);

    return false;
});
唯一适用于 chrome mobile 的答案,因为它针对option元素
2021-04-27 17:15:54

这是一个纯JS解决方案:

element.onmousedown= function(event) {
    //this == event.target
    event.preventDefault();
    var scroll_offset= this.parentElement.scrollTop;
    this.selected= !this.selected;
    this.parentElement.scrollTop= scroll_offset;
}
element.onmousemove= function(event) {
    event.preventDefault();
}

在选择/取消选择选项之前,查看父元素(选择框)并记录垂直滚动偏移。然后在您执行操作后手动重置它。

阻止该mousemove事件的默认行为背后的原因是因为如果您不阻止它并且您在移动鼠标时碰巧单击了一个选项,则所有选项都将被取消选择。

这是一个似乎适用于 Chrome FF 和 IE 的解决方案。它不是非常漂亮,因为单击时它会闪烁一点。

var vals = [];
$("select[multiple]").click(function(e){
        var scroll_offset= this.scrollTop;
      var newVals = $(this).val();
    if (newVals.length === 1) {
        var index = vals.indexOf(newVals[0])
        if (index > -1) {
        vals.splice(index, 1);
      } else {
        vals.push(newVals[0])
      }
      $(this).val(vals);
      this.scrollTop = scroll_offset;
    }
});

提琴手

对于 chrome 中的纯 js 解决方案,请将事件侦听器设置为“onmouseup”。将滚动重置为第一个元素的事件在鼠标向上时触发。例如:

element.onmouseup = function(event) {
    event.preventDefault();
    var st = this.scrollTop;
    setTimeout(function () { element.scrollTop = st; }, 0);
};