如何通过编程告诉 HTML SELECT 下拉(例如,由于鼠标悬停) ?

如何通过编程告诉 HTML select下拉(例如,由于鼠标悬停) ?

114241 次浏览

我可能错了,但我不相信这是可能的默认选择框。您可以使用 JS 和 CSS 做一些事情,以达到预期的结果,但是(据我所知)不能使用普通的 SELECT。

您不能使用 HTML select 标记来实现这一点,但是您可以使用 JavaScript还有HTML 来实现这一点。有很多现有的控件可以做到这一点-例如,“建议”列表附加到 SO“有趣/忽略标签”条目,或 Gmail 的电子邮件地址查找。

有许多 JavaScript + HTML 控件提供了这种功能——查找自动完成控件以获得想法。

请参阅自动补全控件的链接... http://ajaxcontroltoolkit.codeplex.com/

这是我能得到的最接近的结果,改变 onmouseover 元素的大小,并恢复 onmouseout 元素的大小:

<select onMouseOut="this.size=1;" onMouseOver="this.size=this.length;">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>

这是我找到的最好的方法。注意,它只能在 Windows 上使用 IE,你的网页可能需要在一个安全区域-因为我们访问 shell。技巧是 ALT-Down 箭头是打开选择下拉菜单的快捷键。

<button id="optionsButton" style="position:absolute;top:10px;left:10px;height:22px;width:100px;z-index:10" onclick="doClick()">OPTIONS</button>
<select id="optionsSelect" style="position:absolute;top:10px;left:10px;height:20px;width:100px;z-index:9">
<option>ABC</option>
<option>DEF</option>
<option>GHI</option>
<option>JKL</option>
</select>
<script type="text/javascript">
function doClick() {
optionsSelect.focus();
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.SendKeys("%{DOWN}");
}
</script>

这不完全是您要求的,但我喜欢这个解决方案的简单性。在大多数情况下,我想要启动一个下拉列表,这是因为我验证用户实际上已经作出了选择。我改变了下拉菜单的大小并对焦,这很好地突出了他们跳过的内容:

$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();

这在 HTML + J 的 avascript 中曾经是可行的,尽管其他地方的人们都说它不可行,但是它后来被弃用了,现在也不起作用了。

然而,这只在 Chrome 中有效。如果你感兴趣,请阅读更多。


根据 W3C HTML5工作草案,第3.2.5.1.7节交互式内容:

HTML 中的某些元素具有激活行为,这意味着用户可以激活它们。这会触发一系列依赖于激活机制的事件[ ... ] 例如使用键盘或语音输入,或通过鼠标点击

当用户以单击以外的方式触发具有已定义激活行为的元素时,交互事件的默认操作必须运行合成单击激活步骤将在该元素上执行。

<select>是一种交互式内容,我相信可以通过编程方式显示它的 <option>。在玩了几个小时之后,我发现使用 document.createEvent().dispatchEvent()是可行的。

这就是说,演示时间。 这是一把能用的小提琴


HTML:

<select id="dropdown">
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" onclick="runThis()">Show dropdown items</button>​

Javascript:

// <select> element displays its options on mousedown, not click.
showDropdown = function (element) {
var event;
event = document.createEvent('MouseEvents');
event.initMouseEvent('mousedown', true, true, window);
element.dispatchEvent(event);
};


// This isn't magic.
window.runThis = function () {
var dropdown = document.getElementById('dropdown');
showDropdown(dropdown);
};

如果有人能在 Chrome 中找到同样的方法,那就是 请随意修改这把小提琴

当你想做的时候,不要再认为一件事是不可能的,没有什么是不可能的。

使用这个由一个家伙创建的扩展 JS 函数。

Http://code.google.com/p/expandselect/

包含这个 JS,然后把这个参数作为你的选择标识来传递,就像这样:

ExpandSelect(MySelect)

如果还有人在找这个:

<select id="dropdown">
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" >Show dropdown items</button>

Javascript:

var is_visible=false;


$(document).ready(function(){


$('#fire').click(function (e) {
var element = document.getElementById('dropdown');




if(is_visible){is_visible=false; return;}
is_visible = true;


var event;
event = document.createEvent('MouseEvents');
event.initMouseEvent('mousedown', true, true, window);
element.dispatchEvent(event);


/* can be added for i.e. compatiblity.
optionsSelect.focus();
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.SendKeys("%{DOWN}");
*/
e.stopPropagation();
return false;
});




$(document).click(function(){is_visible=false; });
});

更新:

直到这个问题没有完美的解决方案,但是你可以尝试避免这种情况。你为什么要这么做。我想知道一个解决方案,几个月前为移动设备选择插件

Https://github.com/hemantnegi/jquery.sumoselect

最后使用透明的 select 元素屏蔽自定义 div (或任何其他元素) ,以便它可以直接与用户交互。

Xavier Ho 的答案涵盖了目前大多数浏览器中如何解决这个问题。但是,不再使用 JavaScript 来分派/修改事件是一个很好的实践。(就像这个案例中的 mousedown)

从53 + 版本开始,谷歌浏览器 将不会对不受信任的事件执行默认操作。例如通过脚本创建或修改的事件,或通过 dispatchEvent方法发送的事件。这个更改是为了与 Firefox 和 IE 对齐,我认为它们已经没有执行这个操作了。

为了测试的目的,小提琴提供了 Xavier 的答案不会在 chrome 53 + 中工作。(我不测试 FF 和 IE)。

参考连结:

Https://www.chromestatus.com/features/5718803933560832 Https://www.chromestatus.com/features/6461137440735232

InitMouseEvent 也是 不赞成

我认为这在 Chrome 中已经不可能了。

似乎第53版的铬禁用这一功能所述的阿西姆 K T。

根据说明书 Http://www.w3.org/tr/dom-level-3-events/#trusted-events

Trusted Events 不应触发默认操作(单击 事件)。

但是他们在 webview 中启用了它,但是我还没有测试过这个。

我们发现一些 webview 在他们的内部使用快速点击 由于存在损坏的风险,我们将允许鼠标在选定内容上下滑 即使他们不被信任。

在这个 讨论中,让开发人员以编程方式打开下拉菜单的想法被抛弃了。

我也有同样的问题,我发现解决这个问题的更简单的方法是使用 HTML 和 CSS。

首先,让你的 <select>透明(opacity: 0;)。然后,把按钮放在 <select>上。按钮上的点击将被 <select>组件捕获。

select{
opacity: 0;
position: absolute;
}
<select>
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
</select>
<button>click</button>

通过本问题中提到的一些变通方法和类似的方法,打开“ HTML 选择”是可能的。然而,更简单的方法是向项目中添加一个选择库,比如“ select2”或“ select”。 例如,以编程方式打开 select2就像下面这样简单:

$('#target-select').select2('open');

如果还有人在找这个, 我就是这么解决的。

这个解决方案基于这样一个事实,即选定内容看起来像是在增加大小时展开的。我们可以增加尺寸,使它看起来扩大。然后缩小,让它看起来闭合。这样我们就可以通过聚焦和模糊侦听器来处理大多数用例。

选择元素需要绝对定位,因为增加尺寸会增加元素的垂直高度。如果下面有元素,如果不这样做,它们将被下推。

我有一个包装器代码,它包装元素并提供打开和关闭方法。

检查这个小提琴的用法: https://jsfiddle.net/10ar2ebd/16/

var SelectionWrapper = function(element, maxSize, selectCb) {


var preventDefault = function(e) {
e.preventDefault();
e.stopPropagation();
}


var isOpen = false;


var open = function() {
if (!isOpen) {
element.size = maxSize;
// Remove prevent default so that user will be able to select the option
// Check why we prevent it in the first place below
element.removeEventListener('mousedown', preventDefault);
// We focus so that we can close on blur.
element.focus();
isOpen = true;
}
};


var close = function() {
if (isOpen) {
element.size = 1;
// Prevent default so that the default select box open behaviour is muted.
element.addEventListener('mousedown', preventDefault);
isOpen = false;
}
};


// For the reason above
element.addEventListener('mousedown', preventDefault);


// So that clicking elsewhere closes the box
element.addEventListener('blur', close);


// Toggle when click
element.addEventListener('click', function(e) {
if (isOpen) {
close();
// Call ballback if present
if(selectCb) {
selectCb(element.value);
}
} else {
open();
}
});




return {
open: open,
close: close
};
};


// Usage
var selectionWrapper = SelectionWrapper(document.getElementById("select_element"), 7, function(value) {
var para = document.createElement("DIV");
para.textContent = "Selected option: " + value;
document.getElementById("result").appendChild(para);
});


document.getElementById("trigger").addEventListener('click', function() {
selectionWrapper.open();
});

这是 https://jsfiddle.net/NickU/ahLy83mk/50/的解决方案

它使用 size = “ x”打开下拉列表,同时保持下拉列表和父级位置。代码还使用 CSS 样式在不需要时隐藏正确的滚动区域。我修改了在 stackoverflow 上找到的代码,修复了问题并添加了样式。

HTML:

<div>DIV example: <select id="dropdownDiv">
<option value="Alpha">Alpha</option>
<option value="Beta">Beta</option>
<option value="Gamma">Gamma</option>
</select>
</div>


<table id='tab1'>
<tr><td>Empty Cell</td></tr>
<tr><td> <select id="dropdown1">
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
</td>
<tr><td><select id="dropdown2">
<option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="15">1</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option></select>
</td></tr>
<tr><td>Empty Cell</td></tr></table>
<br><button id="fire" type="button" onclick="openDropdown('dropdownDiv', this)" >Show dropdownDiv items</button>
<button id="fire" type="button" onclick="openDropdown('dropdown1', this)" >Show dropdown1 items</button>
<button id="fire" type="button" onclick="openDropdown('dropdown2', this)" >Show dropdown2 items</button>

JavaScript:

  var lastClosedElem = null;
var maxItemsInDropDown = 12;
function openDropdown(elementId, opener)
{
if (lastClosedElem !== null && lastClosedElem === opener)
{
lastClosedElem = null;
return;
}
lastClosedElem = opener;
     

function down()
{
var $this = $(this);


var td = $this.closest('td,div');
if (td && td.length > 0)
td.height(td.height());


var pos = $this.offset();
var len = $this.find("option").length;
if (len > 1 && len < maxItemsInDropDown)
{
$this.addClass('no-scroll');
$this.addClass('noArrow');
}
else if (len > maxItemsInDropDown)
{
len = maxItemsInDropDown;
}


$this.css("position", "absolute");


var _zIndex = $this.css("zIndex");
if (!_zIndex)
_zIndex = 'auto';
$this.attr("_zIndex", _zIndex);
$this.css("zIndex", 9999);


$this.attr("size", len); // open dropdown
$this.unbind("focus", down);
$this.focus();
}


var up = function()
{
var $this = $(this);
$this.css("position", "static");
$this.attr("size", "1");
$this.removeClass('no-scroll');
$this.removeClass('noArrow');


var _zIndex = $this.attr("zIndex");
if (_zIndex)
{
$this.css("zIndex", _zIndex);
}
$this.unbind("blur", up);
$this.unbind("click", upClick);
$this.focus();
}


function upClick(e)
{
up.call(this);
lastClosedElem = null;
}


$("#" + elementId).focus(down).blur(up).click(upClick).trigger('focus');
}

CSS:

.no-scroll { cursor: pointer;}
.no-scroll::-webkit-scrollbar {display:none;}
.no-scroll::-moz-scrollbar {display:none;}
.no-scroll::-o-scrollbar {display:none;}
.no-scroll::-google-ms-scrollbar {display:none;}
.no-scroll::-khtml-scrollbar {display:none;}




.noArrow {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding-left: 3px;
padding-right: 3px;
}




/* Cosmetic styles */
#tab1 tbody tr:nth-child(even) > td, div
{   background: linear-gradient( 180deg, #efefef 1%, #eeeeee 15%, #e2e2e2 85%);
}
        

#tab1 tbody tr td
{   padding: 4px;
}
        

#tab1
{   border: 1px solid silver;
}

我不知道我是否完全理解了这个问题,但是打开一个下拉菜单,这个简单的方法对我很有用。

你有一个元素:

<span onclick="openDropdown();">Open dropdown</span>

你有一个下拉列表:

<select class="dropdown">
<option value="A">Value A</option>
<option value="B">Value B</option>
<option value="C">Value C</option>
</select>

使用 JavaScript,你可以做到以下几点:

document.querySelector('.dropdown').focus();
let elSelected = null;
function bindSelectClick(el){
if(el.target !== elSelected){
$(elSelected).trigger('blur');
$(document).unbind('click', bindSelectClick)
}
}


$('select.shared_date').on('focus', function (){
// do something
elSelected = this;
$(document).on('click', bindSelectClick)


}).on('blur', function (){
// do something
}).on('change', function (){
// do something
})

选择菜单关闭后不会失去焦点。 使用一个单独的函数,我们检查单击是在选择上还是在其他地方。如果元素不相等,那么可以触发某种事件