如何以编程方式告诉 HTML SELECT 下拉(例如,由于鼠标悬停)

How can you programmatically tell an HTML SELECT to drop down (for example, due to mouseover)?

本文关键字:例如 悬停 鼠标 于鼠标 下拉 编程 方式告 SELECT HTML      更新时间:2023-09-26
如何

以编程方式告诉 HTML select下拉(例如,由于鼠标悬停(?

这曾经在HTML+Javascript中实际上是可能的,尽管其他地方的人都说它不是,但它后来被弃用了,现在不起作用。

但是,这仅适用于Chrome。如果您有兴趣,请阅读更多内容。

<小时 />

根据 W3C HTML5 工作草案第 3.2.5.1.7 节。互动内容:

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

当用户以单击元素

以外的方式触发具有定义的激活行为的元素时,交互事件的默认操作必须是对该元素运行合成单击激活步骤。

<select>作为一个交互式内容,我相信可以以编程方式显示其<option>。 经过几个小时的玩法,我发现使用document.createEvent().dispatchEvent()是有效的。

也就是说,演示时间。 这是一个工作小提琴。

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

如果有人找到一种方法可以做同样的事情,但不是在Chrome中,请随时修改这个小提琴。

Xavier Ho的答案是涵盖如何在目前大多数浏览器中解决问题。但是,最好不要再通过 JavaScript 调度/修改"事件了。(比如,在这种情况下mousedown(

从版本 53+ 开始,谷歌浏览器将不会对不受信任的事件执行默认操作。例如通过脚本创建或修改的事件,或通过dispatchEvent方法调度的事件。此更改是为了与我认为尚未执行该操作的Firefox和IE保持一致。

出于测试目的,Fiddle提供了Xavier的答案在chrome 53+中不起作用。(我不测试FF和IE(。

参考链接:

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

并且 initMouseEvent 也被弃用

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

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

select{
  opacity: 0;
  position: absolute;
}
select:hover~button {
  background: orange;
}
 div * {
 width: 100px;
}
<div>
  <select>
    <option>option 1</option>
    <option>option 2</option>
    <option>option 3</option>
  </select>
  <button>click</button>
</div>

这是我

能得到的最接近的,在鼠标悬停时更改元素的大小,并在鼠标输出时恢复大小:

<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>

你不能用HTML选择标签来做到这一点,但你可以用JavaScriptHTML来做到这一点。有各种各样的现有控件可以执行此操作 - 例如,附加到SO"有趣/忽略标签"条目的"建议"列表,或Gmail对电子邮件地址的查找。

有许多 JavaScript+HTML 控件提供此功能 - 寻找自动完成控件以获取想法。

有关自动完成控件,请参阅此链接...http://ajaxcontroltoolkit.codeplex.com/

我认为这在Chrome中不再可能。

似乎chrome版本53禁用了此功能,如Asim K T所述。

根据规格 http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events

受信任事件不应触发默认操作(单击 事件(。

但是,他们已经在 webview 中启用了它,但我还没有对此进行测试。

我们发现一些网络视图在其中使用快速单击,并且 由于存在损坏的风险,我们将允许鼠标按下选择 即使他们不受信任。

在此讨论中,放弃了让开发人员以编程方式打开下拉列表的想法。

如果有人仍在寻找这个:

<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

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

这是我

找到的最好的方法。注意:它仅适用于Windows上的IE,并且您的Web可能需要位于安全区域中 - 因为我们访问shell。诀窍是 ALT 向下箭头是打开选择下拉列表的快捷键。

<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>

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

这是一个基于以下事实的解决方案:当大小增加时,选择看起来像是扩展的。我们可以增加大小以使其看起来扩展。并减少以使其看起来关闭。通过这种方式,我们只需让听众聚焦和模糊即可处理大多数用例。

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

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

检查此小提琴的用法: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; 
}

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

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

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

包含这个 JS,只需调用它传递参数作为您的选择 id,如下所示:

ExpandSelect(MySelect)

我可能是错的,但我认为默认选择框是不可能的。你可以用JS和CSS做一些事情来达到预期的结果,但不能(据我所知(vanilla SELECT。

这不是您所要求的,但我喜欢这个解决方案的简单性。在大多数情况下,我想启动下拉列表,这是因为我正在验证用户是否确实进行了选择。我更改了下拉列表的大小并聚焦它,这很好地突出显示了他们跳过的内容:

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

通过此问题和类似问题中提到的一些解决方法,可以打开"HTML 选择"。但是,更简洁的方法是将选择库添加到您的项目中,例如"select2"或"selected"。例如,以编程方式打开 select2 就像:

$('#target-select').select2('open');
<style>
select{
  overflow:hidden;
}
</style>
<select id="select">
  <option value="1">First option</option>
  <option value="2">Second second</option>
  <option value="3">Third option</option>
</select>
<script>
select.size = select.length;
select.onclick =()=> {
  select.size = 1;
}
</script>

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

您有一个元素:

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

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