Javascript “最佳实践原型”;单击任意位置以关闭";?

Javascript “最佳实践原型”;单击任意位置以关闭";?,javascript,prototypejs,Javascript,Prototypejs,我发现自己经常会在网页中打开一个元素(例如下拉菜单),如果用户单击页面上除元素本身以外的任何位置,我就会关闭该元素 为了简单起见,我主要是自己编写代码,而不是使用一些下拉菜单类 然而,我从未成功地构建过一个完全令人满意的实现:事件处理和冒泡在不同的浏览器中工作方式不同,需要紧急的解决方法,在某些情况下,单击下拉按钮会在同一时刻开始关闭它,等等 是否有一个基于原型、权威的最佳实践可以做到这一点?可以跨浏览器工作的东西-IE6是一个加号,但不是一个要求 仅此而已: 单击按钮-打开一个元素 (例如,

我发现自己经常会在网页中打开一个元素(例如下拉菜单),如果用户单击页面上除元素本身以外的任何位置,我就会关闭该元素

为了简单起见,我主要是自己编写代码,而不是使用一些下拉菜单类

然而,我从未成功地构建过一个完全令人满意的实现:事件处理和冒泡在不同的浏览器中工作方式不同,需要紧急的解决方法,在某些情况下,单击下拉按钮会在同一时刻开始关闭它,等等

是否有一个基于原型、权威的最佳实践可以做到这一点?可以跨浏览器工作的东西-IE6是一个加号,但不是一个要求

仅此而已:

  • 单击按钮-打开一个元素 (例如,绝对定位的下拉菜单)
  • 在元素内单击-元素保持打开状态
  • 单击打开元件的按钮t-元件保持打开状态
  • 单击页面上的任何其他位置-元素关闭

我只需要事件处理部分的帮助,菜单的显示完全是次要的。

好吧,你需要制作一个窗口大小的不可见div,将它放在当前元素的后面,并在其中添加一个单击事件。

只是大声思考,但你可能可以使用下拉菜单上的模糊事件来隐藏它(当元素失去焦点时会触发模糊)或者另一个想法是,当下拉列表打开时,将一个单击事件附加到隐藏下拉列表的文档对象。事件通过其容器传播,因此它最终应该到达文档对象。当下拉列表被单击时,您可能需要调用preventPropegation,以便它不会到达处理程序附加到文档。

也许您可以计算clickevent的位置(X,Y),并将其与所需容器的累积偏移量(累积偏移量)+[el.宽度| el.高度]进行比较

Event.observe(window, 'click', function(e) {

  var el = $('el')

  if( el.cumulativeOffset[0] < e.Event.pointerX(e) ...  )

});

<div id="el" style="position:absolute;width:100px;height:100px;background-color:#00F;top:100px;left:300px;">

</div>
事件观察(窗口“点击”功能(e){
变量el=$('el')
如果(el.cumulativeOffset[0]
您还可以向不希望触发关闭操作的项添加特定类,并在其中进行检查

if (!event.element().hasClassName('dont_close'))   
  Element.remove(selectDOMElement);

我猜“打开”按钮在菜单中

$('openbutton').observe('click' function(event) {
    var menu = $('openbutton').up();

    if (menu.hasClassName('collapsed')) {

        menu.removeClassName('collapsed');
        menu.addClassName('expanded');

        document.observe('click', function (event) {
            if(!event.target.descendantOf(menu)) {
                menu.addClassName('collapsed');
                menu.removeClassName('expanded');
            }
        });

    } else {
        menu.addClassName('collapsed');
        menu.removeClassName('expanded');
    }
});

这是一种可行的方法,但我想避免它,因为这样你就不能立即单击页面上的其他内容。关闭元素总是需要单击一次。因此,当你说“单击页面上的任何其他位置-元素关闭”时你的意思是你想在该点上执行默认的点击操作?你可以做一些非常粗糙的事情,比如计算点击的位置,然后……不,这是一个非常糟糕的主意。你在其他网站上有任何关于你的要求的实例吗?好的,本质上我要寻找的是一个正常的
菜单。你可以打开它,将鼠标移动到任何你想要的地方,但如果你单击其他任何地方,它将立即关闭。这是个好主意,但打开元素时不需要聚焦。不过,我正在寻找一个解决事件传播问题的有效方法,这只是与onClick有关。这是一个创造性的想法,但有太多的东西我认为可能会出错。我认为需要事件驱动才能真正安全。
$('openbutton').observe('click' function(event) {
    var menu = $('openbutton').up();

    if (menu.hasClassName('collapsed')) {

        menu.removeClassName('collapsed');
        menu.addClassName('expanded');

        document.observe('click', function (event) {
            if(!event.target.descendantOf(menu)) {
                menu.addClassName('collapsed');
                menu.removeClassName('expanded');
            }
        });

    } else {
        menu.addClassName('collapsed');
        menu.removeClassName('expanded');
    }
});