web-dev-qa-db-fra.com

Comment masquer le tiroir lorsque l'utilisateur clique dessus

Comment masquer le tiroir lorsque l'utilisateur clique sur un élément? Ou quand un bouton est cliqué?

<div class="mdl-layout__drawer">
        <span class="mdl-layout-title">Title</span>
        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect" id="clickme">
          <i class="material-icons">add</i>
        </button>
</div>

Comment puis-je faire que lorsque le bouton est cliqué, le tiroir sera caché comme si je cliquais à l'extérieur du tiroir? J'ai essayé de simuler un événement de clic en dehors du tiroir, mais il ne cache toujours pas.

13
krato

Je crois que vous pouvez supprimer la classe is-visible de .mdl-layout__drawer. J'ai essayé de modifier un exemple de code sur leur site: demo . Ma liaison d'événements javascript pur est rouillée, mais comme je l'ai mentionné, il vous suffit de supprimer la classe .is-visible du tiroir.

Mettre à jour

Le code que j'ai fourni était pour v1.0.0 de mdl et n'est plus réel. À partir de v1.1.0, une API publique est disponible pour basculer le tiroir, comme décrit dans Réponse de Benjamin. Si vous avez entre v1.0.6 et v1.1.0, jetez un œil à idleherb's answer .

7
jdepypere

toggleDrawer est maintenant une fonction publique depuis @ be54f78 .

var layout = document.querySelector('.mdl-layout');
layout.MaterialLayout.toggleDrawer();

Non disponible actuellement avec la v1.0.6, vous devrez donc construire à partir du source (à ce jour).

22
Benjamin

Basé sur le discours de GitHub , j'ai quelques solutions de travail à la question (espérons-nous bientôt résolue) d'avoir un tiroir MDL fermé lorsque le lien est cliqué. En ce moment, j'utilise:

function close() {
  var d = document.querySelector('.mdl-layout');
  d.MaterialLayout.toggleDrawer();
}

document.querySelector('.mdl-layout__drawer').addEventListener('click', close);

Les autres variations sont:

1.

document.querySelector('.mdl-layout__drawer').addEventListener('click', function () {
  document.querySelector('.mdl-layout__obfuscator').classList.remove('is-visible');
  this.classList.remove('is-visible');
}, false);

2.

function close() {
  var d = document.querySelector('.mdl-layout');
  d.MaterialLayout.toggleDrawer();
}
var drawer_container = document.getElementsByClassName('mdl-layout')[0];
drawer_container.querySelector('.mdl-layout__drawer').addEventListener('click', 'close');

Quelqu'un au cours de la discussion a mentionné l’idée de cibler la querySelector afin de ne pas demander à parcourir tout le document et j’ai proposé les deux variantes suivantes:

3.

var drawer_container = document.getElementsByClassName('mdl-layout')[0]; 
# no IDs in the html code.
drawer_container.querySelector('.mdl-layout__drawer').addEventListener('click', function () {
  var obfuscator = document.querySelector('.mdl-layout__obfuscator');
  if (obfuscator.classList.contains('is-visible')) {
    obfuscator.classList.remove('is-visible');
    this.classList.remove('is-visible');
  }
}, false);

4.

function close() {
  var d = document.getElementsByClassName('mdl-layout__container')[0].querySelector('.mdl-layout');
  d.MaterialLayout.toggleDrawer();
}
var drawer_container = document.getElementsByClassName('mdl-layout')[0];
drawer_container.querySelector('.mdl-layout__drawer').addEventListener('click', 'close');

Dans mes deux versions, le navigateur doit exécuter document.getElementsByClassName ainsi qu'un appel cibléquerySelector.

Dans ma première version, il y a également le contrôle: classList.contains('is-visible') recommandé par quelqu'un, mais qui semble inutile car la fonction est appelée à partir d'un élément visible uniquement si classList.contains('is-visible') est vrai.

J'ai ajouté les appels suivants à chacune de mes variantes (n ° 3 et 4), à l'intérieur les fonctions:

console.time("anonymous");
console.timeEnd("anonymous");
console.time("close function");
console.timeEnd("close function");

Et celui avec l'instruction if s'exécute en .39ms. Sans l'instruction if, ils s'exécutent tous les deux dans .19ms. Mais je ne mesure pas non plus les méthodes getElementsByClassName et querySelector qui, si je comprends bien, s'exécutent au chargement de la page.

Lorsque j'ai exécuté console.time("first"); et console.timeEnd("first"); tout au long du premier code, et pour moi, le code le plus joli, le temps était 23ms.

Apparemment, ie8, que je veux supporter, ne supporte pas getElementsByClassName .

J'espère que quelqu'un pourra fournir et expliquer une optimale solution à ce problème relativement simple.

Voici un CodePen (pas le mien). 

7
MikeiLL

Pour la version 1.0.6, vous devez supprimer la classe mentionnée précédemment de deux éléments:

$( '.mdl-layout__drawer, .mdl-layout__obfuscator' ).removeClass( 'is-visible' );
4
idleherb

J'utilise cette commande jQuery:

$( 'div[class^="mdl-layout__obfuscator"]' ).trigger( "click" );
3
user5738952

Je ne sais pas comment insérer "MaterialLayout" dans mon projet Angular 6, mais j'ai pris leur fonction de prototype et je l'ai utilisée dans mon composant:

  toggleDrawer = function () {
    var is_drawer_open = 'is-visible'
    var drawerButton = document.querySelector('.mdl-layout__drawer-button');
    var drawer_ = document.querySelector('.mdl-layout__drawer');
    var obfuscator_ = document.querySelector('.mdl-layout__obfuscator');
    drawer_.classList.toggle(is_drawer_open);
    obfuscator_.classList.toggle(is_drawer_open);
    // Set accessibility properties.
    if (drawer_.classList.contains(is_drawer_open)) {
      drawer_.setAttribute('aria-hidden', 'false');
      drawerButton.setAttribute('aria-expanded', 'true');
    } else {
      drawer_.setAttribute('aria-hidden', 'true');
      drawerButton.setAttribute('aria-expanded', 'false');
    }
  };
0
Stef

Faire ceci:

HTML

<div class="mdl-layout__drawer" id="mobile-left-menu">
    <span class="mdl-layout-title">Whatever</span>
    <nav class="mdl-navigation inject-navigation">
          <a class="mdl-navigation__link" href="#" page="home">Home</a>
          <a class="mdl-navigation__link" href="#About" page="about">About</a>
    </nav>
</div>

JS

    $('.mdl-navigation__link').on('click', function () {

        // close the drawer the button is clicked
        $('.mdl-layout__drawer').toggleClass('is-visible')
    });

CSS

/* prevent the dark transparent background over the page with the drawer is open */
.mdl-layout__obfuscator.is-visible{
    background-color: transparent;
}
0
Mahmoud Zalt

Masquer automatiquement le tiroir de navigation dans Material Design Lite Framework.

Incluez simplement ce code dans la balise script de votre page Web

Vous devez inclure jQuery pour obtenir cette exécution ...: D

<script>
$(document).ready(function(){
    $(".mdl-layout__drawer a").click(function(){
        $(".mdl-layout__drawer,.mdl-layout__obfuscator").toggleClass("is-visible");
    });
});
</script>
0
Chandra Shekhar

Pour le fermer, vous devez d'abord vérifier qu'il est ouvert, car il n'y a pas de "closeDrawer". Ceci est utile lorsque vous ne pouvez pas supposer qu'il est déjà ouvert, par exemple si vous avez un bouton de déconnexion dans le tiroir, mais également à l'extérieur ou dans certaines fonctions de délai de session. Vous avez juste besoin que ce soit fermé pour afficher le formulaire de connexion.

closeDrawer() {
    let drawer = document.querySelector('.mdl-layout__drawer');
    if (drawer && drawer.className.indexOf("is-visible")>-1) {
        toggleDrawer();
    }
}
toggleDrawer() {
    let layout = document.querySelector('.mdl-layout');
    if (layout && layout.MaterialLayout) {
        layout.MaterialLayout.toggleDrawer();
    }
}
0
Stephen

Dans Angular ^ 4.0.0 , vous pouvez utiliser cette solution de contournement au lieu d'utiliser toggleDrawer() si vous rencontrez des problèmes pour avoir MaterialLayout non défini en tant que je suis.

(
  document
    .querySelector('.mdl-layout__obfuscator') as HTMLDivElement
).click();
0
AndreaM16

Afficher et masquer le menu est aussi simple que d’ajouter et de supprimer la classe .is-visible car elle peut être vue dans le source :

MaterialLayout.prototype.drawerToggleHandler_ = function() {
  'use strict';

  this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
};

Donc, vous auriez quelque chose comme ça:

function toggle_drawer() {
  var drawer = document.getElementsByClassName('mdl-layout__drawer')[0];
  drawer.classList.toggle("is-visible");
}

J'espérais une méthode plus pratique du widget MaterialLayout, mais le mieux que j'ai trouvé est la suivante:

var layout = document.getElementsByClassName('mdl-layout')[0];
layout.MaterialLayout.drawerToggleHandler_();

bien que cela fonctionne, _ à la fin du nom de la méthode indique que cette fonction n'est pas censée être (mal) utilisée comme méthode d'API publique.

0
Yan Foto