最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Prototype best practice for "click anywhere to close"? - Stack Overflow

programmeradmin3浏览0评论

I find myself very often in the situation that I open an element in a web page - e.g. a drop-down menu - that I want to close if the user clicks anywhere on the page except the element itself.

To keep things simple, I have mostly written the code myself instead of employing some drop-down menu class.

However, I have never managed to build an implementation of this that was pletely satisfying: Event handling and bubbling would work differently in different browsers, there would be the need for nasty workarounds, in some situations clicking the drop-down button would start closing it in the same moment, and so on.

Is there a Prototype based, authoritative, best practice to do this? Something that works across browsers - IE6 being a plus but not a requirement?

Just this:

  • click on a button - an element opens (e.g. an absolutely positioned drop-down menu).
  • click within the element - the element stays open.
  • click on the button that opened the element - the element stays open.
  • click anywhere else on the page - the element closes.

I need help with the event handling part only, the displaying of the menu is totally secondary.

I find myself very often in the situation that I open an element in a web page - e.g. a drop-down menu - that I want to close if the user clicks anywhere on the page except the element itself.

To keep things simple, I have mostly written the code myself instead of employing some drop-down menu class.

However, I have never managed to build an implementation of this that was pletely satisfying: Event handling and bubbling would work differently in different browsers, there would be the need for nasty workarounds, in some situations clicking the drop-down button would start closing it in the same moment, and so on.

Is there a Prototype based, authoritative, best practice to do this? Something that works across browsers - IE6 being a plus but not a requirement?

Just this:

  • click on a button - an element opens (e.g. an absolutely positioned drop-down menu).
  • click within the element - the element stays open.
  • click on the button that opened the element - the element stays open.
  • click anywhere else on the page - the element closes.

I need help with the event handling part only, the displaying of the menu is totally secondary.

Share Improve this question edited Dec 29, 2011 at 15:49 Rob W 349k87 gold badges807 silver badges682 bronze badges asked Dec 17, 2009 at 13:58 PekkaPekka 450k148 gold badges986 silver badges1.1k bronze badges 2
  • Do you have any examples of your requirements in practice on other sites? – Skilldrick Commented Dec 17, 2009 at 14:18
  • Well, in essence what I'm looking for is the behaviour of a normal <select> menu. You can open it, move the mouse wherever you want but if you click anywhere else, it will close right away. – Pekka Commented Dec 17, 2009 at 14:58
Add a ment  | 

5 Answers 5

Reset to default 4
Event.observe(document, 'click', function (event) {
  switch (event.element().id) {
    case 'example_id':
      // do different stuff depending on element clicked
      // ofc u don't need to pass id, u can simply throw an element itself
      break;
    default:
      // do close action
      break;
  }
  // also check Event.findElement();
});

You can also add specific classes to the items you don't want to trigger close action and check it inside

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

I guess the open button is within the menu.

$('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');
    }
});

AFAIK, you need to make an invisible div the size of window, put it behind the current element, and add a click event to that.

Just thinking out loud but you might be able to use the blur event on the dropdown to hide it (blur gets fired when an element loses focus) or another idea might be when the dropdown opens attach a click event to the document object that hides the dropdown. Events get propagated through their containers so it should end up at the document object eventually. You might need to call preventPropegation on the event when your dropdown gets clicked so that it doesn't make it to the handler attached to the document.

maybe you could calculate the Position (X,Y) for the clickevent and pare that to the cumulativeOffset (cumulativeScrollOffset) + [el.width|el.height] of the desired container.

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>
发布评论

评论列表(0)

  1. 暂无评论