5 votes

Prototype de meilleure pratique pour "cliquer n'importe où pour fermer" ?

Je me retrouve très souvent dans la situation où j'ouvre un élément dans une page web - par exemple un menu déroulant - que je veux fermer si l'utilisateur clique sur n'importe où dans la page, sauf l'élément lui-même .

Pour garder les choses simples, j'ai surtout écrit le code moi-même au lieu d'employer une classe de menu déroulant.

Cependant, je n'ai jamais réussi à construire une implémentation de ce système qui soit totalement satisfaisante : La gestion des événements et des bulles fonctionnait différemment selon les navigateurs, il fallait trouver des solutions de contournement, dans certaines situations, le fait de cliquer sur le bouton déroulant entraînait sa fermeture au même moment, etc.

Existe-t-il une meilleure pratique basée sur le Prototype, faisant autorité, pour faire cela ? Quelque chose qui fonctionne sur tous les navigateurs - IE6 étant un plus mais pas une exigence ?

Juste ça :

  • cliquer sur un bouton - un élément s'ouvre (par exemple, un menu déroulant positionné de manière absolue).
  • cliquez dans l'élément - l'élément reste ouvert.
  • cliquez sur le bouton qui a ouvert l'élément t - l'élément reste ouvert.
  • cliquez n'importe où ailleurs sur la page - l'élément se ferme.

J'ai besoin d'aide pour la partie traitement des événements uniquement, l'affichage du menu est totalement secondaire.

4voto

Tomasz Durka Points 381
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();
});

Vous pouvez également ajouter des classes spécifiques aux éléments que vous ne souhaitez pas voir déclencher une action de fermeture et les vérifier à l'intérieur.

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

2voto

blq Points 21

Je suppose que le bouton d'ouverture se trouve dans le 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');
    }
});

1voto

Skilldrick Points 33002

À ma connaissance, vous devez créer une division invisible de la taille de la fenêtre, la placer derrière l'élément actuel et lui ajouter un événement de clic.

0voto

John Duff Points 7602

Je réfléchis à voix haute, mais vous pourriez utiliser l'événement blur sur le menu déroulant pour le masquer (le blur est déclenché lorsqu'un élément perd le focus). Une autre idée serait d'attacher un événement click à l'objet document lorsque le menu déroulant s'ouvre, afin de masquer le menu déroulant. Les événements se propagent à travers leurs conteneurs et devraient donc finir par atteindre l'objet document. Il se peut que vous deviez appeler preventPropegation sur l'événement lorsque votre liste déroulante est cliquée afin qu'il n'atteigne pas le gestionnaire attaché au document.

0voto

nils petersohn Points 463

Vous pourriez peut-être calculer la position (X,Y) du clickevent et la comparer au cumulativeOffset (cumulativeScrollOffset) + [el.width|el.height] du conteneur souhaité.

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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X