从html选择元素中选择多个而不使用ctrl键

时间:2014-07-03 02:06:07

标签: javascript jquery html

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

基本上,我发现不得不按住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中使用它。此外,我对使用选择列表的任何替代解决方案不感兴趣。

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

7 个答案:

答案 0 :(得分:33)

您可以保存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/

答案 1 :(得分:5)

这是一个纯粹的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事件的默认行为背后的原因是因为如果您不阻止它并且您在移动鼠标时碰巧单击某个选项,则所有选项都将被取消选中。

答案 2 :(得分:2)

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

我已经将一些解决方案合并到一起,至少在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;
});

答案 3 :(得分:0)

这是一个似乎适用于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;
    }
});

jsfiddle

答案 4 :(得分:0)

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

(window as any).open(someUrl, "_blank");

答案 5 :(得分:0)

这对我来说比其他建议更好,因为它是香草JS,并且其行为与原始静止图像更为相似,例如,可以通过Shift键快速选择许多项目。

element.onmousedown = function(event) {
    if (event.shiftKey) return;
    event.preventDefault();
    this.focus();
    var scroll = this.scrollTop;
    event.target.selected = !event.target.selected;
    this.scrollTop = scroll;
    // make sure that other listeners (like Vue) pick up on the change
    // even though we prevented the default.
    this.dispatchEvent(new Event("change"));
}

答案 6 :(得分:0)

快速版简短版本

已建立 进行中

// this is for specyfic id  -> $('#WOStatusKey').

//below for all multiple select
$('select[multiple]').mousedown(e=>{
e.target.selected = !e.target.selected;
e.stopPropagation();
return false;
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple id="WOStatusKey" name="WOStatusKey">                
        <option value="1">Created</option>
        <option value="2">In Process</option>
        <option value="3">Bla bla bla</option>
    </select>

相关问题