HTMLselect元素closures时是否会触发DOM事件?

我正在寻找一个DOM事件,我可以通过JavaScript来监听,当一个select元素被打开(但没有任何选项改变),然后点击select元素,在页面的其他地方(任何地方)closures。

这不是selectblur事件,因为select保留焦点。 同样,它不是某个其他元素或文档的focus事件,也不是clickclick窗口,文档或主体。

这不是select的change事件,因为select中的选项没有被更改。

我不关心传统的Internet Explorer,只需要在符合标准的现代浏览器中工作即可。 虽然专有的黑客可能值得了解。

我创build了一个JSFiddle来演示这个问题: http : //jsfiddle.net/premasagar/FpfnM/

  1. 点击“结果”面板上的select框
  2. 单击标记为“HERE”(或其他任何地方)的文本,只需单击一下,看是否有任何事件添加到日志中。 最新的Chrome或Firefox中没有发生任何事件。

所以问题是: 什么JavaScript可以被添加,以获得点击select框时logging的事件?

(我在这里问了一个类似的,但不同的问题:
iOS上的JavaScript:打开HTMLselect元素 )

不幸的是,当select框closures或打开时,没有标准事件,所以你的代码将变得非常多毛,并且适应不同的浏览器。 也就是说,我认为这是可以做到的,而且我已经在Firefox中使用mouseup事件得到了一些帮助。

http://jsfiddle.net/FpfnM/50/

在Firefox(我假设Chrome),你将需要非常仔细地跟踪select的状态。 当按下blur键或发生blur事件时,您需要更新状态以将其标识为已closures。 我没有在我的演示中实现,你可以看到如果你点击转义而不是点击select会发生什么。

Safari中的事情比较容易,select中的mousedown事件表示打开select,并且select的任何closures都由click事件表示。

如果你发现浏览器中没有这些事件触发,你可以尝试一个额外的技巧。 因为像select和textarea这样的表单部件经常由操作系统渲染,而不是在浏览器内部,所以你可能会和它们交互,而某些消息可能不会传到浏览器的事件处理程序。 如果在打开select框时将一个覆盖屏幕的透明textarea放置在较低的z-index处,则可能可以使用它来跟踪该closures点击。 它可以捕获浏览器DOM元素可能错过的事件。

更新: Chrome浏览器在打开时会看到选定内容,而在打开select内容时则会在文档上显示鼠标hover。 以下是适用于Chrome的版本:

http://jsfiddle.net/FpfnM/51/

再次,你需要做一些浏览器检测来处理每一个正确的行为。 特别是Chrome的一个问题是,当您再次点击selectclosures它时,不会触发任何事件。 但是,您可以检测到页面点击。

快速总结:

 Chrome/Safari: select.mousedown on open, document.mouseup on close Firefox: select.click on open, document.mouseup on close IE8/IE7: select.click on open, document.mouseup on close 

对于其他会表示closures(escape keypress,blur等)的事件,有很多边缘情况,但是这些是处理用户点击select框然后点击进入文档区域。

希望这可以帮助!

按照JSFiddle的指示,我得到以下事件:

 BODY, mousedown, STRONG #document, mousedown, STRONG window, mousedown, STRONG SELECT, blur, SELECT BODY, click, STRONG #document, click, STRONG window, click, STRONG 

这些都是在select菜单已经处于焦点和展开状态之后单击“HERE”时触发的所有事件。 这是最新版本的Chrome。

这些中的任何一个都不应该满足你的目的?

编辑:如果你想确保它是你的Select元素失去焦点,设置一个全局的Javascriptvariables,'selectFocused',并将其设置为False。 当select菜单收到焦点时将其设置为True,并在发生上述任何事件时将其设置为False。 现在可以在代码的任何地方使用'selectFocused'来检测你的Select元素当前是否有焦点,当它改变值时,你知道你的Select元素已经被选中或者未被选中。

我的第一个直觉就是要实现这个目标,那就是使用通常用来closures媒体外的(自定义)下拉菜单的代码:

 function clickInBody(){ functionToCallOnBlur(); } function clickInBodyStop(event){ event.stopPropagation(); } 

然后在您的body标签上添加onClick="clickInBody()"并在您添加onClick="clickInBodyStop(event)"select项上添加。 这应该每次单击页面时调用事件,但是如果您单击select标记,它将停止传播,而不是调用functionToCallOnBlur()

先决条件:使用jQuery! 这可能只会解决你的问题的一部分,但如果你正在寻找一个事件触发,当你点击一个元素,你可以使用覆盖div。

当用户点击select框时:

 $('#mySelectBox').click(function () { var myOverlayDiv = $('<div id="overlayDiv" class="overlayDiv"></div>') .click(function () { // call your "select lost focus" function here // which should include $('#overlayDiv').remove() somewhere! }) .show() .appendTo(document.body); }); 

样式为覆盖div:

 .overlayDiv { position:absolute; top:0; left:0; width:100%; height:100%; opacity:0; z-index:1000; } 

你需要确保你的select框菜单是一个更高的Z – 索引,所以当用户点击菜单,他们得到菜单,而不是叠加分区:)

当你有更多的1下拉菜单:

  $("select").each(function () { var initDropdown = $(this); initDropdown.data("open", false); console.log(this.name + " closed"); initDropdown.on("blur", function () { var blurDdopdown = $(this); blurDdopdown.data("open", false); console.log(this.name + " closed"); }); }); $("select").bind("click", function () { var clickedDropdown = $(this); if (clickedDropdown.data('open') == false) { clickedDropdown.data('open', true); console.log(this.name + " open"); } else { clickedDropdown.data('open', false); console.log(this.name + " closed"); } });