【问题标题】:Selecting multiple from an html select element without using ctrl key在不使用 ctrl 键的情况下从 html 选择元素中选择多个
【发布时间】:2014-08-23 23:55:04
【问题描述】:

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

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

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

【问题讨论】:

  • 你可以为此做一个小提琴,以便其他人也可以试验你的代码吗?
  • 什么浏览器?在 chrome 中看不到问题
  • janaspage:在您的链接上,向下滚动并单击一个选项。选择后,选择框会自动将位置重置为最顶部(就像您一直向上滚动一样)。 aa333:jsfiddle.net/h5Sw2

标签: javascript jquery html


【解决方案1】:

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

【讨论】:

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

【讨论】:

  • 唯一适用于 chrome mobile 的答案,因为它针对 option 元素
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        这对我来说比其他建议更有效,因为它是原版 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"));
        }
        

        【讨论】:

          【解决方案7】:

          简短的快速版本

          已创建 进行中

          // 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>

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-25
            • 2011-01-23
            • 2015-10-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多