如何避免使用 Javascript 在多选框中按 ctrl-click 的需要?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8641729/
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
How to avoid the need for ctrl-click in a multi-select box using Javascript?
提问by bokov
I thought this would be a simple hack, but I've now been searching for hours and can't seen to find the right search term. I want to have an ordinary multiple select box (<select multiple="multiple">
) except I don't want the user to have to hold down the control key to make multiple selections.
我认为这将是一个简单的黑客攻击,但我现在已经搜索了几个小时,但找不到正确的搜索词。我想要一个普通的多选框 ( <select multiple="multiple">
),除非我不希望用户必须按住控制键才能进行多选。
In other words, I want a left click to toggle the <option>
element that's under the cursor without changing any of the others. In other other words, I want something that looks like a combo list box but behaves like a group of check boxes.
换句话说,我希望左键单击来切换<option>
光标下的元素,而不更改任何其他元素。换句话说,我想要一些看起来像组合列表框但行为像一组复选框的东西。
Can anybody suggest a simple way to do this in Javascript? Thanks.
任何人都可以建议一种在 Javascript 中执行此操作的简单方法吗?谢谢。
回答by techfoobar
Check this fiddle: http://jsfiddle.net/xQqbR/1022/
检查这个小提琴:http: //jsfiddle.net/xQqbR/1022/
You basically need to override the mousedown
event for each <option>
and toggle the selected
property there.
您基本上需要覆盖mousedown
每个事件<option>
并在selected
那里切换属性。
$('option').mousedown(function(e) {
e.preventDefault();
$(this).prop('selected', !$(this).prop('selected'));
return false;
});
For simplicity, I've given 'option' as the selector above. You can fine tune it to match <option>s
under specific <select>
element(s). For ex: $('#mymultiselect option')
为简单起见,我将 'option' 作为上面的选择器。您可以微调它以匹配<option>s
特定<select>
元素。例如:$('#mymultiselect option')
回答by Sergio
Had to solve this problem myself and noticed the bugged behavior a simple interception of the mousedown
and setting the attribute would have, so made a override of the select element and it works good.
必须自己解决这个问题,并注意到简单的拦截mousedown
和设置属性会产生的错误行为,因此覆盖了 select 元素并且效果很好。
jsFiddle: http://jsfiddle.net/51p7ocLw/
jsFiddle:http: //jsfiddle.net/51p7ocLw/
Note:This code does fix buggy behavior by replacing the select element in the DOM. This is a bit agressive and will break event handlers you might have attached to the element.
注意:此代码通过替换 DOM 中的 select 元素确实修复了错误行为。这有点激进,会破坏您可能附加到元素的事件处理程序。
window.onmousedown = function (e) {
var el = e.target;
if (el.tagName.toLowerCase() == 'option' && el.parentNode.hasAttribute('multiple')) {
e.preventDefault();
// toggle selection
if (el.hasAttribute('selected')) el.removeAttribute('selected');
else el.setAttribute('selected', '');
// hack to correct buggy behavior
var select = el.parentNode.cloneNode(true);
el.parentNode.parentNode.replaceChild(select, el.parentNode);
}
}
<h4>From</h4>
<div>
<select name="sites-list" size="7" multiple>
<option value="site-1">SITE</option>
<option value="site-2" selected>SITE</option>
<option value="site-3">SITE</option>
<option value="site-4">SITE</option>
<option value="site-5">SITE</option>
<option value="site-6" selected>SITE</option>
<option value="site-7">SITE</option>
<option value="site-8">SITE</option>
<option value="site-9">SITE</option>
</select>
</div>
回答by evilReiko
techfoobar's answer is buggy, it unselects all options if you drag the mouse.
techfoobar 的回答有问题,如果您拖动鼠标,它会取消选择所有选项。
Sergio's answer is interesting, but cloning and removing events-bound to a dropdown is not a nice thing.
Sergio 的回答很有趣,但是克隆和删除绑定到下拉列表的事件并不是一件好事。
Note: Doesn't work on Firefox, but works perfectly on Safari/Chrome/Opera. (I didn't test it on IE)
注意:在 Firefox 上不起作用,但在 Safari/Chrome/Opera 上完美运行。(我没有在 IE 上测试过)
回答by Stefan Steiger
Necromancing.
The selected answer without jQuery.
Also, it missed setting the focus when an option is clicked, because you have to do this yourself, if you write e.preventDefault...
Forgetting to do focus would affect CSS-styling, e.g. bootstrap, etc.
死灵法术。
没有 jQuery 的选定答案。
此外,当一个选项被点击时,它错过了设置焦点,因为你必须自己做这件事,如果你写 e.preventDefault...
忘记做焦点会影响 CSS 样式,例如引导程序等。
var options = [].slice.call(document.querySelectorAll("option"));
options.forEach(function (element)
{
// console.log("element", element);
element.addEventListener("mousedown",
function (e)
{
e.preventDefault();
element.parentElement.focus();
this.selected = !this.selected;
return false;
}
, false
);
});
回答by Marino Di Clemente
I had same problem today, generally the advice is to use a list of hidden checkboxes and emulate the behavior via css, in this way is more easy to manage but in my case i don't want to modify html.
我今天遇到了同样的问题,一般建议是使用隐藏复选框列表并通过 css 模拟行为,这样更容易管理,但在我的情况下,我不想修改 html。
At the moment i've tested this code only with google chrome, i don't know if works with other browser but it should:
目前我只用谷歌浏览器测试了这段代码,我不知道是否适用于其他浏览器,但它应该:
var changed;
$('select[multiple="multiple"]').change(function(e) {
var select = $(this);
var list = select.data('prevstate');
var val = select.val();
if (list == null) {
list = val;
} else if (val.length == 1) {
val = val.pop();
var pos = list.indexOf(val);
if (pos == -1)
list.push(val);
else
list.splice(pos, 1);
} else {
list = val;
}
select.val(list);
select.data('prevstate', list);
changed = true;
}).find('option').click(function() {
if (!changed){
$(this).parent().change();
}
changed = false;
});
Of course suggestions are welcome but I have not found another way
当然欢迎提出建议,但我还没有找到其他方法