如何避免在使用Javascript的多选框中按Ctrl键点击?

我认为这将是一个简单的黑客攻击,但我现在已经search了几个小时,无法find正确的search字词。 我想有一个普通的多选框( <select multiple="multiple"> ),除了我不想让用户按住控制键进行多选。

换句话说,我想要左键单击切换光标下方的<option>元素,而不更改任何其他元素。 换句话说,我想看起来像一个组合列表框,但行为像一组checkbox。

任何人都可以build议一个简单的方法来在Javascript中做到这一点? 谢谢。

检查这个小提琴: http : //jsfiddle.net/xQqbR/1022/

你基本上需要重写每个<option>mousedown事件,并在那里切换selected属性。

 $('option').mousedown(function(e) { e.preventDefault(); $(this).prop('selected', !$(this).prop('selected')); return false; }); 

为了简单起见,我已经给出了“选项”作为上面的select器。 您可以对其进行微调以匹配特定<select>元素下的<option>s 。 例如: $('#mymultiselect option')

自己必须解决这个问题,并注意到bug的行为,简单的mousedown拦截和设置属性将有,所以重写了select元素,它的效果很好。

jsFiddle: http : //jsfiddle.net/51p7ocLw/

注意:这段代码通过replaceDOM中的select元素来解决bug的行为。 这有点激进,会打破你可能附加到元素的事件处理程序。

 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的答案是越野车,它会取消select所有选项,如果你拖动鼠标。

塞尔吉奥的回答很有意思,但克隆和删除事件绑定到一个下拉列表不是一件好事。

试试这个答案 。

注意:在Firefox上不起作用,但在Safari / Chrome / Opera上完美工作。 (我没有在IE上testing)

我今天有同样的问题,一般build议是使用隐藏checkbox的列表,并通过CSS来模拟行为,这样更容易pipe理,但在我的情况下,我不想修改HTML。

目前,我只用谷歌浏览器testing了这个代码,我不知道是否适用于其他浏览器,但它应该:

 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; }); 

当然欢迎提供build议,但我还没有find其他方法