我以为这将是一个简单的技巧,但是我已经搜索了几个小时,找不到合适的搜索词。我希望有一个普通的多重选择框(<select multiple="multiple">
),但我不想用户必须按住控制键才能进行多重选择。
换句话说,我希望单击鼠标左键来切换<option>
光标下方的元素,而不更改其他任何元素。换句话说,我想要的东西看起来像一个组合列表框,但表现得像一组复选框。
有人可以建议用Javascript做到这一点的简单方法吗?谢谢。
Answers:
检查此小提琴:http : //jsfiddle.net/xQqbR/1022/
基本上,您需要mousedown
为每个事件覆盖事件<option>
并在selected
那里切换属性。
$('option').mousedown(function(e) {
e.preventDefault();
$(this).prop('selected', !$(this).prop('selected'));
return false;
});
为了简单起见,我在上面给出了“选项”作为选择器。您可以对其进行微调以匹配<option>s
特定<select>
元素。例如:$('#mymultiselect option')
! this.selected
在那里使用。
$(document).ready(...)
this.selected = !this.selected;
确实不需要使用jQuery
我本人要解决此问题,并注意到错误的行为是对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>
e.preventDefault()
)。只是要记住一点。
e.preventDefault()
办?
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。
目前,我仅使用google chrome测试了此代码,但不知道是否可以在其他浏览器上使用,但应该:
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;
});
当然可以提出建议,但我没有找到其他方法
<select multiple>
。 小提琴中的演示