【问题标题】:How to hide drawer upon user click如何在用户单击时隐藏抽屉
【发布时间】:2015-10-10 18:06:30
【问题描述】:

当用户点击一个项目时如何隐藏抽屉?或者当一个按钮被点击时?

<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>

如何做到当单击按钮时,抽屉将被隐藏,就像我在抽屉外单击一样?我尝试在抽屉外模拟点击事件,但它仍然没有隐藏。

【问题讨论】:

    标签: javascript material-design material-design-lite


    【解决方案1】:

    我相信您可以从.mdl-layout__drawer 中删除is-visible 类。我尝试从他们的网站修改 codepen 示例:demo。我的纯 javascript 事件绑定是生锈的,但正如我所提到的,您只需从抽屉中删除 .is-visible 类。

    更新

    我提供的代码是针对 mdl 的 v1.0.0 的,不再是实际的。 v1.1.0 开始,提供了一个用于切换抽屉的公共 API,如 Benjamin's answer 中所述。如果您介于v1.0.6v1.1.0 之间,请查看idleherb's answer

    【讨论】:

    • 也请检查其他答案之一。 .mdl-layout__obfuscator 也需要删除。我认为这应该是公认的答案
    • @Mageshkhanna 显然自去年 7 月以来发生了很大变化,但我的代码示例显然有效,所以我不太明白你为什么需要对此投反对票。我的代码适用于版本 1.0.0,即提出问题时处于活动状态的版本。
    • 对不起,伙计!现在更新了:)
    • 有谁知道如何检查抽屉是否打开。如果抽屉已经关闭,我不想触发 toggleDrawer,因为它会打开它。
    • @Lancelot 我知道这有点晚了,但我在下面的回答中提到了这一点。
    【解决方案2】:

    显示和隐藏菜单就像添加和删除 .is-visible 类一样简单,因为它可以看到 in the source

    MaterialLayout.prototype.drawerToggleHandler_ = function() {
      'use strict';
    
      this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
    };
    

    所以你会有这样的东西:

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

    我希望有一个更方便的 MaterialLayout 小部件方法,但我想出的最好的方法是:

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

    虽然这恰好起作用,但方法名称末尾的 _ 表明该函数不应该(错误)用作公共 API 方法。

    【讨论】:

      【解决方案3】:

      对于 1.0.6 版本,您必须从两个元素中删除前面提到的类:

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

      【讨论】:

        【解决方案4】:

        我正在使用这个 jquery 命令:

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

        【讨论】:

          【解决方案5】:

          toggleDrawer 现在是自 @be54f78 以来的公共函数。

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

          当前不适用于 v1.0.6,因此您需要从源代码构建(从今天开始)。

          【讨论】:

          【解决方案6】:

          这样做:

          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;
          }
          

          【讨论】:

            【解决方案7】:

            基于GitHub discourse,对于单击链接时关闭 MDL 抽屉的问题(希望很快得到解决),我有几个可行的解决方案。目前我正在使用:

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

            其他变体是:

            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');
            

            讨论中有人提到了以querySelector 为目标的想法,这样就不需要查看整个文档,我想出了以下两种变体:

            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');
            

            在我的两个版本中,浏览器都必须运行 document.getElementsByClassName 以及 targeted querySelector 调用。

            在我的第一个版本中,还有有人推荐的检查:classList.contains('is-visible'),但这似乎没有必要,因为该函数是从一个只有在 classList.contains('is-visible') 为真时才可见的项目调用的。

            我在每个变体(#3 和 4)中添加了以下调用,函数中:

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

            带有if 语句的语句在.39ms 中运行。如果没有if 语句,它们都在.19ms 中运行。但我也没有测量 getElementsByClassNamequerySelector 方法,如果我理解正确的话,它们会在页面加载时运行。

            当我运行console.time("first");console.timeEnd("first"); 通过第一个,对我来说,最漂亮的代码时,时间是23ms

            显然是ie8,我想支持,doesn't support getElementsByClassName

            我希望有人可以为这个相对简单的问题提供和解释一个最佳解决方案。

            这是CodePen(不是我的)。

            【讨论】:

            • 对于“Material Kit - v1.1.1.0”,您的第一个建议非常有效(无需更改)
            • 感谢您让我和其他人知道。
            【解决方案8】:

            在 Material Design Lite Framework 中自动隐藏导航抽屉。

            只需将此代码包含在网页的脚本标记中

            必须包含 jQuery 才能运行... :D

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

            【讨论】:

              【解决方案9】:

              要关闭它,您需要先检查它是否打开,因为没有“closeDrawer”。当您不能假设它已经打开时,这很有帮助,例如您在抽屉内、外部或某些会话超时功能中有一个注销按钮。您只需将其关闭即可显示重新登录表单。

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

              【讨论】:

                【解决方案10】:

                在 Angular ^4.0.0 中,如果您在像我一样未定义 MaterialLayout 时遇到问题,则可以使用此解决方法而不是使用 toggleDrawer()

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

                【讨论】:

                  【解决方案11】:

                  我不知道如何在我的 Angular 6 项目中获取“MaterialLayout”,但我采用了他们的原型函数并在我的组件中使用它:

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

                  【讨论】:

                    【解决方案12】:

                    将此代码添加到自定义按钮“点击”事件 (在 1.3.0 版本上测试)

                    $(".mdl-layout__drawer, .mdl-layout__obfuscator").toggleClass("is-visible");
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-11-04
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-01-06
                      • 2020-09-23
                      相关资源
                      最近更新 更多