如何使用 jQuery 在多选中切换选项的选择?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2096259/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 12:45:39  来源:igfitidea点击:

How to toggle selection of an option in a multi-select with jQuery?

jqueryhtmlselect

提问by tim

I have a standard select multipleHTML Input field, for example:

我有一个标准的select multipleHTML 输入字段,例如:

<select multiple="multiple" size="5" id="mysel" name="countries"> 
    <option value="2">Afghanistan</option> 
    <option value="4">Aland</option> 
</select>

As this is a multi-select, to select more than one value you have to hold the CTRLkey and select any further elements. However what I want to achieve is, that:

由于这是一个多选,要选择多个值,您必须按住CTRL键并选择任何其他元素。但是我想要实现的是:

  1. Clicking an UNSELECTED option SELECTs it
  2. Clicking a SELECTED option UNSELECTS it.
  1. 单击一个 UNSELECTED 选项选择它
  2. 单击 SELECTED 选项取消选择它。

The idea is to avoid having to press the CTRLkey and change the usage semantics of this input field. Elements should only be selectable and un-selectable by clicking (ie. toggling of the select status).

这个想法是为了避免必须按下CTRL键并更改此输入字段的使用语义。元素应该只能通过单击来选择和不可选择(即切换选择状态)。

I have not yet been able to implement this. The pseudo-code should look something like this.

我还没有能够实现这一点。伪代码应该是这样的。

  1. Catch a Click event.
  2. Check if the element that was clicked was unselected, then select it
  3. Or if the element that was clicked was selected, then unselect it.
  1. 捕获 Click 事件。
  2. 检查被点击的元素是否未被选中,然后选中它
  3. 或者,如果单击的元素被选中,则取消选中它。

How should I implement this?

我应该如何实施?

回答by Tim Banks

You may use the following snippet to achieve your desired effect

您可以使用以下代码段来实现您想要的效果

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

   if ($self.prop("selected"))
          $self.prop("selected", false);
   else
       $self.prop("selected", true);

   return false;
});

In older versions of jQuery, where prop()was not available:

在旧版本的 jQuery 中,哪里prop()不可用:

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

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

   return false;
});

回答by user250120

You're right in wanting to change the default behaviour of select multiple input fields. They tend to contribute negatively towards user experience as the purpose is not clearly conveyed and users' may not understand how to use them correctly.

您想要更改选择多个输入字段的默认行为是正确的。它们往往会对用户体验产生负面影响,因为目的没有明确传达,用户可能不了解如何正确使用它们。

Re-purposing a multi-select box isn't right either. If you are considering using select multiple, then you might want to refactor your design. Perhaps you can use checkboxes instead?

重新使用多选框也不对。如果您正在考虑使用多选,那么您可能需要重构您的设计。也许您可以改用复选框?

Here's an article on the topic: http://www.ryancramer.com/journal/entries/select_multiple/

这是关于该主题的文章:http: //www.ryancramer.com/journal/entries/select_multiple/

回答by duindain

I just tried this solution and the selected answer did not work for Jquery 1.9.1

我刚刚尝试了这个解决方案,所选的答案对 Jquery 1.9.1 不起作用

The answer by Oscar looked much better but it mixed properties with attributes and doesnt work if you select, de-select then try to select again as it puts the select into an unusable state

Oscar 的答案看起来好多了,但它混合了属性和属性,如果您选择,则取消选择然后尝试再次选择,因为它将选择置于无法使用的状态。

I have found the correct answer for me was the following

我找到了对我来说正确的答案如下

$("select[multiple] option").mousedown(function () {
       if ($(this).prop("selected"))
           $(this).prop("selected", false);
       else
           $(this).prop("selected", true);
       return false;    });

I hope this helps others ;)

我希望这可以帮助其他人;)

回答by Vedmant

Another variant without JQuery:

另一个没有 JQuery 的变体:

var multiSelect = {};

function init() {      
  var s = document.getElementsByTagName('select');
  for (var i = 0; i < s.length; i++) {
    if (s[i].multiple) {
      var n = s[i].name;
      multiSelect[n] = [];
      for (var j = 0; j < s[i].options.length; j++) {
        multiSelect[n][j] = s[i].options[j].selected;
      }
      s[i].onclick = changeMultiSelect;
    }
  }
}

function changeMultiSelect() {
  var n = this.name;
  for (var i=0; i < this.options.length; i++) {
    if (this.options[i].selected) {
      multiSelect[n][i] = !multiSelect[n][i];
    }
    this.options[i].selected = multiSelect[n][i];
  }
}

window.onload = init;

回答by Yeo

Javascript (without jquery):

Javascript(没有jquery):

var select = document.getElementById('mysel');
select.addEventListener('mousedown', function(e){
    var opt = e.target;
    if (opt.selected){
        opt.removeAttribute('selected');
        opt.selected = false;
    } else {
        opt.setAttribute('selected', '');
        opt.selected = true;
    }
    e.preventDefault();
});

I see most of the answers above are binding the event with the option instead of the select. If my select has 1000 options, then it will bind 1000 events, will it affect the performance?

我看到上面的大多数答案都将事件与选项绑定而不是选择。如果我的select有1000个选项,那么它会绑定1000个事件,会影响性能吗?

Because of this I also decide not to bind my event in the option.

因此,我也决定不在选项中绑定我的事件。

回答by Constantin.FF

Probably some fix coming with the new jQuery versions:

新的 jQuery 版本可能会带来一些修复:

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

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

回答by oaamados

Using jquery 1.9.1 the javascript code is:

使用 jquery 1.9.1 的 javascript 代码是:

   $("select[multiple] option").mousedown(function () {
       var $self = $(this);
       if ($self.prop("selected"))
           $self.removeAttr("selected");
       else
           $self.attr("selected", "selected");
       return false;
   });