我认为这将是一个简单的黑客攻击,但我现在已经搜索了几个小时,但找不到正确的搜索词。我想要一个普通的多选框 ( <select multiple="multiple">
),除非我不希望用户必须按住控制键才能进行多选。
换句话说,我想要左键单击来切换<option>
光标下的元素而不更改任何其他元素。换句话说,我想要一些看起来像组合列表框但行为像一组复选框的东西。
任何人都可以建议一种在 Javascript 中执行此操作的简单方法吗?谢谢。
我认为这将是一个简单的黑客攻击,但我现在已经搜索了几个小时,但找不到正确的搜索词。我想要一个普通的多选框 ( <select multiple="multiple">
),除非我不希望用户必须按住控制键才能进行多选。
换句话说,我想要左键单击来切换<option>
光标下的元素而不更改任何其他元素。换句话说,我想要一些看起来像组合列表框但行为像一组复选框的东西。
任何人都可以建议一种在 Javascript 中执行此操作的简单方法吗?谢谢。
检查这个小提琴:http : //jsfiddle.net/xQqbR/1022/
您基本上需要覆盖mousedown
每个事件<option>
并在selected
那里切换属性。
$('option').mousedown(function(e) {
e.preventDefault();
$(this).prop('selected', !$(this).prop('selected'));
return false;
});
为简单起见,我将 'option' 作为上面的选择器。您可以微调它以匹配<option>s
特定<select>
元素。例如:$('#mymultiselect option')
必须自己解决这个问题,并注意到一个简单的拦截mousedown
和设置属性会产生的错误行为,因此覆盖了 select 元素并且效果很好。
注意:此代码通过替换 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>
techfoobar的答案是错误的,如果您拖动鼠标,它会取消选择所有选项。
Sergio的回答很有趣,但是克隆和删除绑定到下拉列表的事件并不是一件好事。
注意:在 Firefox 上不起作用,但在 Safari/Chrome/Opera 上完美运行。(我没有在 IE 上测试过)
在我最初的回答之后 5 年,我认为这里的最佳做法是用复选框替换下拉列表。想想看,这就是复选框首先存在的主要原因,它可以很好地与旧浏览器(如 IE 和现代手机)配合使用,无需任何自定义 JS 来处理所有古怪的场景。
死灵法术。
没有 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
);
});
我今天遇到了同样的问题,一般建议是使用隐藏复选框列表并通过 css 模拟行为,这样更容易管理,但在我的情况下,我不想修改 html。
目前我只用谷歌浏览器测试了这段代码,我不知道是否适用于其他浏览器,但它应该:
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;
});
当然欢迎提出建议,但我还没有找到其他方法