【问题标题】:How do I detect a click outside an element?如何检测元素外的点击?
【发布时间】:2010-09-14 06:09:40
【问题描述】:

我有一些 HTML 菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外点击时,我想隐藏这些元素。

用 jQuery 可以实现这样的事情吗?

$("#menuscontainer").clickOutsideThisElement(function() {
    // Hide the menus
});

【问题讨论】:

标签: javascript jquery click


【解决方案1】:

对于某些人来说,这可能是一个更好的解决方案。

$(".menu_link").click(function(){
    // show menu code
});

$(".menu_link").mouseleave(function(){
    //hide menu code, you may add a timer for 3 seconds before code to be run
});

我知道 mouseleave 不仅意味着在外部单击,还意味着离开该元素的区域。

一旦菜单本身位于menu_link 元素内,那么单击或继续菜单本身就不会有问题。

【讨论】:

  • mouseleave 和某种 hack 可能会为某些人解决这个问题,这是一个测试 jsfiddle.net/1r73jm8m
【解决方案2】:

我相信最好的方法是这样的。

$(document).on("click", function(event) {
  clickedtarget = $(event.target).closest('#menuscontainer');
  $("#menuscontainer").not(clickedtarget).hide();
});

这种类型的解决方案很容易适用于多个菜单以及通过 javascript 动态添加的菜单。基本上它只允许您单击文档中的任何位置,并检查您单击的元素,并选择它最接近的“#menuscontainer”。然后它会隐藏所有的 menuscontainers 但不包括你点击的那个。

不确定您的菜单是如何构建的,但请随意将我的代码复制到 JSFiddle 中。这是一个非常简单但功能齐全的菜单/模式系统。您需要做的就是构建 html 菜单,代码将为您完成工作。

https://jsfiddle.net/zs6anrn7/

【讨论】:

    【解决方案3】:

    我知道这个问题有一百万个答案,但我一直喜欢使用 HTML 和 CSS 来完成大部分工作。在这种情况下,z-index 和定位。我发现最简单的方法如下:

    $("#show-trigger").click(function(){
      $("#element").animate({width: 'toggle'});
      $("#outside-element").show();
    });
    $("#outside-element").click(function(){
      $("#element").hide();
      $("#outside-element").hide();
    });
    #outside-element {
      position:fixed;
      width:100%;
      height:100%;
      z-index:1;
      display:none;
    }
    #element {
      display:none;
      padding:20px;
      background-color:#ccc;
      width:300px;
      z-index:2;
      position:relative;
    }
    #show-trigger {
      padding:20px;
      background-color:#ccc;
      margin:20px auto;
      z-index:2;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="outside-element"></div>
    <div id="element">
      <div class="menu-item"><a href="#1">Menu Item 1</a></div>
      <div class="menu-item"><a href="#2">Menu Item 1</a></div>
      <div class="menu-item"><a href="#3">Menu Item 1</a></div>
      <div class="menu-item"><a href="#4">Menu Item 1</a></div>
    </div>
    <div id="show-trigger">Show Menu</div>

    这创建了一个安全的环境,因为除非菜单实际打开并且 z-index 保护元素内的任何内容在被点击时不会产生任何错误,否则不会触发任何内容。

    此外,您不需要 jQuery 使用传播调用覆盖所有基础,并且不必清除所有内部元素的失火。

    【讨论】:

      【解决方案4】:
      $(document).on("click",function (event)   
       {   
           console.log(event);
         if ($(event.target).closest('.element').length == 0)
           {
          //your code here
            if ($(".element").hasClass("active"))
            {
              $(".element").removeClass("active");
            }
           }
       });
      

      尝试此编码以获得解决方案。

      【讨论】:

        【解决方案5】:

        该事件有一个名为 event.path 的属性,它是一个“按树顺序排列其所有祖先的静态有序列表”。要检查事件是否源自特定 DOM 元素或其子元素之一,只需检查该特定 DOM 元素的路径。它还可以用于通过在some 函数中逻辑上ORing 元素检查来检查多个元素。

        $("body").click(function() {
          target = document.getElementById("main");
          flag = event.path.some(function(el, i, arr) {
            return (el == target)
          })
          if (flag) {
            console.log("Inside")
          } else {
            console.log("Outside")
          }
        });
        #main {
          display: inline-block;
          background:yellow;
        }
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div id="main">
          <ul>
            <li>Test-Main</li>
            <li>Test-Main</li>
            <li>Test-Main</li>
            <li>Test-Main</li>
            <li>Test-Main</li>
          </ul>
        </div>
        <div id="main2">
          Outside Main
        </div>

        所以对于你的情况应该是

        $("body").click(function() {
          target = $("#menuscontainer")[0];
          flag = event.path.some(function(el, i, arr) {
            return (el == target)
          });
          if (!flag) {
            // Hide the menus
          }
        });
        

        【讨论】:

          【解决方案6】:

          如果有人好奇这里是javascript解决方案(es6):

          window.addEventListener('mouseup', e => {
                  if (e.target != yourDiv && e.target.parentNode != yourDiv) {
                      yourDiv.classList.remove('show-menu');
                      //or yourDiv.style.display = 'none';
                  }
              })
          

          还有 es5,以防万一:

          window.addEventListener('mouseup', function (e) {
          if (e.target != yourDiv && e.target.parentNode != yourDiv) {
              yourDiv.classList.remove('show-menu'); 
              //or yourDiv.style.display = 'none';
          }
          

          });

          【讨论】:

            【解决方案7】:

            这是我解决问题的方法。

            $(window).click(function (event) {
                //To improve performance add a checklike 
                //if(myElement.isClosed) return;
                var isClickedElementChildOfMyBox = isChildOfElement(event,'#id-of-my-element');
            
                if (isClickedElementChildOfMyBox)
                    return;
            
                //your code to hide the element 
            });
            
            var isChildOfElement = function (event, selector) {
                if (event.originalEvent.path) {
                    return event.originalEvent.path[0].closest(selector) !== null;
                }
            
                return event.originalEvent.originalTarget.closest(selector) !== null;
            }
            

            【讨论】:

              【解决方案8】:

              这对我有用

              $("body").mouseup(function(e) {
                  var subject = $(".main-menu");
                  if(e.target.id != subject.attr('id') && !subject.has(e.target).length) {
                      $('.sub-menu').hide();
                  }
              });
              

              【讨论】:

                【解决方案9】:

                这是一个纯javascript的简单解决方案。它是最新的 ES6

                var isMenuClick = false;
                var menu = document.getElementById('menuscontainer');
                document.addEventListener('click',()=>{
                    if(!isMenuClick){
                       //Hide the menu here
                    }
                    //Reset isMenuClick 
                    isMenuClick = false;
                })
                menu.addEventListener('click',()=>{
                    isMenuClick = true;
                })
                

                【讨论】:

                • "Up-to-date with ES6" 是一个相当大胆的声明,因为 ES6 中唯一最新的东西是 () =&gt; {} 而不是 function() {}。你所拥有的被归类为带有 ES6 扭曲的纯 JavaScript。
                • @MortenMoulder:是的。即使它实际上是 ES6,也只是为了引起注意。但只要看看解决方案。我觉得挺好的。
                • It's vanilla JS and works for event target removed from DOM (e.g. when value from inner popup is selected, immediately closing the popup).向我 +1!
                【解决方案10】:

                如果您只想在单击按钮时显示一个窗口,并在单击外部时取消显示此窗口。(或再次单击按钮)此波纹管工作良好

                document.body.onclick = function() { undisp_menu(); };
                var menu_on = 0;
                
                function menu_trigger(event){
                
                    if (menu_on == 0)
                    {
                        // otherwise u will call the undisp on body when 
                        // click on the button
                        event.stopPropagation(); 
                
                        disp_menu();
                    }
                
                    else{
                        undisp_menu();
                    }
                
                }
                
                
                function disp_menu(){
                
                    menu_on = 1;
                    var e = document.getElementsByClassName("menu")[0];
                    e.className = "menu on";
                
                }
                
                function undisp_menu(){
                
                    menu_on = 0;
                    var e = document.getElementsByClassName("menu")[0];
                    e.className = "menu";
                
                }
                

                别忘了这个按钮

                <div class="button" onclick="menu_trigger(event)">
                
                <div class="menu">
                

                和css:

                .menu{
                    display: none;
                }
                
                .on {
                    display: inline-block;
                }
                

                【讨论】:

                  【解决方案11】:

                  如果您使用“Pop-up”之类的工具,则可以使用“onFocusOut”事件。

                  window.onload=function(){
                  document.getElementById("inside-div").focus();
                  }
                  function loseFocus(){
                  alert("Clicked outside");
                  }
                  #container{
                  background-color:lightblue;
                  width:200px;
                  height:200px;
                  }
                  
                  #inside-div{
                  background-color:lightgray;
                  width:100px;
                  height:100px;
                  
                  }
                  <div id="container">
                  <input type="text" id="inside-div" onfocusout="loseFocus()">
                  </div>

                  【讨论】:

                    【解决方案12】:
                    $('#propertyType').on("click",function(e){
                              self.propertyTypeDialog = !self.propertyTypeDialog;
                              b = true;
                              e.stopPropagation();
                              console.log("input clicked");
                          });
                    
                          $(document).on('click','body:not(#propertyType)',function (e) {
                              e.stopPropagation();
                              if(b == true)  {
                                  if ($(e.target).closest("#configuration").length == 0) {
                                      b = false;
                                      self.propertyTypeDialog = false;
                                      console.log("outside clicked");
                                  }
                              }
                            // console.log($(e.target).closest("#configuration").length);
                          });
                    

                    【讨论】:

                      【解决方案13】:

                      我使用了下面的脚本并用 jQuery 完成。

                      jQuery(document).click(function(e) {
                          var target = e.target; //target div recorded
                          if (!jQuery(target).is('#tobehide') ) {
                              jQuery(this).fadeOut(); //if the click element is not the above id will hide
                          }
                      })
                      

                      在下面找到 HTML 代码

                      <div class="main-container">
                      <div> Hello I am the title</div>
                      <div class="tobehide">I will hide when you click outside of me</div>
                      </div>
                      

                      你可以阅读教程here

                      【讨论】:

                        【解决方案14】:

                        我很惊讶没有人真正承认focusout 事件:

                        var button = document.getElementById('button');
                        button.addEventListener('click', function(e){
                          e.target.style.backgroundColor = 'green';
                        });
                        button.addEventListener('focusout', function(e){
                          e.target.style.backgroundColor = '';
                        });
                        <!DOCTYPE html>
                        <html>
                        <head>
                          <meta charset="utf-8">
                        </head>
                        <body>
                          <button id="button">Click</button>
                        </body>
                        </html>

                        【讨论】:

                          【解决方案15】:

                          我只是想让@Pistos 的答案更明显,因为它隐藏在 cmets 中。

                          这个解决方案非常适合我。纯JS:

                          var elementToToggle = $('.some-element');
                          $(document).click( function(event) {
                            if( $(event.target).closest(elementToToggle).length === 0 ) {
                              elementToToggle.hide();
                            }
                          });
                          

                          在 CoffeeScript 中:

                          elementToToggle = $('.some-element')
                          $(document).click (event) ->
                            if $(event.target).closest(elementToToggle).length == 0
                              elementToToggle.hide()
                          

                          【讨论】:

                            【解决方案16】:

                            假设您要检测用户在外部或内部单击的 div 是否具有 id,例如:“my-special-widget”。

                            监听body点击事件:

                            document.body.addEventListener('click', (e) => {
                                if (isInsideMySpecialWidget(e.target, "my-special-widget")) {
                                    console.log("user clicked INSIDE the widget");
                                }
                                console.log("user clicked OUTSIDE the widget");
                            });
                            
                            function isInsideMySpecialWidget(elem, mySpecialWidgetId){
                                while (elem.parentElement) {
                                    if (elem.id === mySpecialWidgetId) {
                                        return true;
                                    }
                                    elem = elem.parentElement;
                                }
                                return false;
                            }
                            

                            在这种情况下,您不会破坏点击页面中某些元素的正常流程,因为您没有使用“stopPropagation”方法。

                            【讨论】:

                              【解决方案17】:

                              首先,您必须使用 mouseenter 和 mouseleave 事件来跟踪鼠标是在 element1 内部还是外部。 然后,您可以创建一个覆盖整个屏幕的 element2 以检测任何点击,并根据您是在 element1 内部还是外部做出相应的反应。

                              我强烈建议同时处理初始化和清理,并且由于显而易见的原因,element2 应尽可能临时化。

                              在下面的示例中,叠加层是位于某处的元素,可以通过单击内部来选择它,而通过单击外部来取消选择。 _init 和 _release 方法被称为自动初始化/清理过程的一部分。 该类继承自具有内部和外部元素的 ClickOverlay,不用担心。我使用了 outerElement.parentNode.appendChild 来避免冲突。

                              import ClickOverlay from './ClickOverlay.js'
                              
                              /* CSS */
                              // .unselect-helper {
                              //  position: fixed; left: -100vw; top: -100vh;
                              //  width: 200vw; height: 200vh;
                              // }
                              // .selected {outline: 1px solid black}
                              
                              export default class ResizeOverlay extends ClickOverlay {
                                  _init(_opts) {
                                      this.enterListener = () => this.onEnter()
                                      this.innerElement.addEventListener('mouseenter', this.enterListener)
                                      this.leaveListener = () => this.onLeave()
                                      this.innerElement.addEventListener('mouseleave', this.leaveListener)
                                      this.selectListener = () => {
                                          if (this.unselectHelper)
                                              return
                                          this.unselectHelper = document.createElement('div')
                                          this.unselectHelper.classList.add('unselect-helper')
                                          this.unselectListener = () => {
                                              if (this.mouseInside)
                                                  return
                                              this.clearUnselectHelper()
                                              this.onUnselect()
                                          }
                                          this.unselectHelper.addEventListener('pointerdown'
                                              , this.unselectListener)
                                          this.outerElement.parentNode.appendChild(this.unselectHelper)
                                          this.onSelect()
                                      }
                                      this.innerElement.addEventListener('pointerup', this.selectListener)
                                  }
                              
                                  _release() {
                                      this.innerElement.removeEventListener('mouseenter', this.enterListener)
                                      this.innerElement.removeEventListener('mouseleave', this.leaveListener)
                                      this.innerElement.removeEventListener('pointerup', this.selectListener)
                                      this.clearUnselectHelper()
                                  }
                              
                                  clearUnselectHelper() {
                                      if (!this.unselectHelper)
                                          return
                                      this.unselectHelper.removeEventListener('pointerdown'
                                          , this.unselectListener)
                                      this.unselectHelper.remove()
                                      delete this.unselectListener
                                      delete this.unselectHelper
                                  }
                              
                                  onEnter() {
                                      this.mouseInside = true
                                  }
                              
                                  onLeave() {
                                      delete this.mouseInside
                                  }
                              
                                  onSelect() {
                                      this.innerElement.classList.add('selected')
                                  }
                              
                                  onUnselect() {
                                      this.innerElement.classList.remove('selected')
                                  }
                              }
                              

                              【讨论】:

                              • 对于已经给出的答案来说,代码太多了......你为什么要做这个?浪费了很多事件监听器,只是为了添加 2 个 onclick,一个在元素上,另一个在 body 上关闭你想要关闭的元素
                              【解决方案18】:

                              const button = document.querySelector('button')
                              const box = document.querySelector('.box');
                              
                              const toggle = event => {
                                event.stopPropagation();
                                
                                if (!event.target.closest('.box')) {
                                  console.log('Click outside');
                              
                                  box.classList.toggle('active');
                              
                                  box.classList.contains('active')
                                    ? document.addEventListener('click', toggle)
                                    : document.removeEventListener('click', toggle);
                                } else {
                                  console.log('Click inside');
                                }
                              }
                              
                              button.addEventListener('click', toggle);
                              .box {
                                position: absolute;
                                display: none;
                                margin-top: 8px;
                                padding: 20px;
                                background: lightgray;
                              }
                              
                              .box.active {
                                display: block;
                              }
                              <button>Toggle box</button>
                              
                              <div class="box">
                                <form action="">
                                  <input type="text">
                                  <button type="button">Search</button>
                                </form>
                              </div>

                              【讨论】:

                              • 对于那些想知道这是如何工作的人,回调toggle 依赖于浏览器的默认事件传播。如果单击在“框”内,请不要隐藏框。否则,切换active 类。如果用户在框外单击或在按钮上单击,请参阅我们需要输入条件。如果我们切换到激活状态,在文档根目录上注册相同的回调,否则会从根目录中删除回调。
                              【解决方案19】:

                              最简单的方法:mouseleave(function())

                              更多信息:https://www.w3schools.com/jquery/jquery_events.asp

                              【讨论】:

                              • 欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.
                              • @Daniil 这是不是一个仅链接的答案。如果链接被删除,第一句话仍然构成答案。
                              • 我同意这不是仅链接的答案,但这不是此问题的答案,因为此答案是鼠标离开元素时,而不是按要求单击时;)
                              【解决方案20】:

                              2020 解决方案使用原生 JS API closest 方法。

                              document.addEventListener('click', ({ target }) => {
                                if (!target.closest('.el1, .el2, #el3')) {
                                  alert('click outside')
                                }
                              })
                              
                              

                              【讨论】:

                                【解决方案21】:

                                还在寻找检测外部点击的完美解决方案吗?不要再看了!介绍Clickout-Event,一个为点击和其他类似事件提供通用支持的包,它适用于所有场景:纯HTMLonclickout属性,.addEventListener('clickout') of vanilla JavaScript,.on('clickout') of jQuery,v-on:clickout Vue.js 的指令,你可以命名它。只要前端框架内部使用addEventListener 来处理事件,Clickout-Event 就可以工作。只需在页面的任何位置添加脚本标签,它就可以像魔术一样工作。

                                HTML 属性

                                <div onclickout="console.log('clickout detected')">...</div>
                                

                                原版 JavaScript

                                document.getElementById('myId').addEventListener('clickout', myListener);
                                

                                jQuery

                                $('#myId').on('clickout', myListener);
                                

                                Vue.js

                                <div v-on:clickout="open=false">...</div>
                                

                                角度

                                <div (clickout)="close()">...</div>
                                

                                【讨论】:

                                  【解决方案22】:

                                  所有这些答案都解决了这个问题,但我想贡献一个完全符合需要的现代 es6 解决方案。我只是希望这个可运行的演示能让人们满意。

                                  window.clickOutSide = (element, clickOutside, clickInside) => {
                                    document.addEventListener('click', (event) => {
                                      if (!element.contains(event.target)) {
                                        if (typeof clickInside === 'function') {
                                          clickOutside();
                                        }
                                      } else {
                                        if (typeof clickInside === 'function') {
                                          clickInside();
                                        }
                                      }
                                    });
                                  };
                                  
                                  window.clickOutSide(document.querySelector('.block'), () => alert('clicked outside'), () => alert('clicked inside'));
                                  .block {
                                    width: 400px;
                                    height: 400px;
                                    background-color: red;
                                  }
                                  &lt;div class="block"&gt;&lt;/div&gt;

                                  【讨论】:

                                    【解决方案23】:

                                    这对我来说很好。我不是专家。

                                    $(document).click(function(event) {
                                      var $target = $(event.target);
                                      if(!$target.closest('#hamburger, a').length &&
                                      $('#hamburger, a').is(":visible")) {
                                        $('nav').slideToggle();
                                      }
                                    });
                                    

                                    【讨论】:

                                      【解决方案24】:

                                      现在是 2020 年,您可以使用 event.composedPath()

                                      发件人:https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath

                                      Event 接口的composedPath() 方法返回事件的路径,这是一个将调用监听器的对象数组。

                                      const target = document.querySelector('#myTarget')
                                      
                                      document.addEventListener('click', (event) => {
                                        const withinBoundaries = event.composedPath().includes(target)
                                      
                                        if (withinBoundaries) {
                                          target.innerText = 'Click happened inside element'
                                        } else {
                                          target.innerText = 'Click happened **OUTSIDE** element'
                                        } 
                                      })
                                      /* just to make it good looking. you don't need this */
                                      #myTarget {
                                        margin: 50px auto;
                                        width: 500px;
                                        height: 500px;
                                        background: gray;
                                        border: 10px solid black;
                                      }
                                      <div id="myTarget">
                                        click me (or not!)
                                      </div>

                                      【讨论】:

                                      • 非常感谢!
                                      【解决方案25】:

                                      我已经阅读了 2021 年的所有内容,但如果没有错的话,没有人建议像这样简单的方法来取消绑定和删除事件。使用上述两个答案和一个小技巧,将所有内容合二为一(也可以将参数添加到函数中以传递选择器,以获得更多弹出窗口)。 可能有人知道这个笑话也可以通过这种方式完成:

                                      <div id="container" style="display:none"><h1>my menu is nice but disappear if i click outside it</h1></div>
                                      
                                      <script>
                                       function printPopup(){
                                        $("#container").css({ "display":"block" });
                                        var remListener = $(document).mouseup(function (e) {
                                         if ($(e.target).closest("#container").length === 0 && (e.target != $('html').get(0))) 
                                         {
                                          //alert('closest call');
                                          $("#container").css({ "display":"none" });
                                          remListener.unbind('mouseup'); // isn't it?
                                         } 
                                        });
                                       }
                                      
                                       printPopup();
                                      
                                      </script>
                                      

                                      干杯

                                      【讨论】:

                                        【解决方案26】:

                                        使用focusout 获取可访问性

                                        这里有一个答案说(非常正确)关注click 事件是一个可访问性问题,因为我们想要满足键盘用户的需求。 focusout 事件在这里使用是正确的,但它可以比其他答案更简单(在纯 javascript 中也是如此):

                                        一种更简单的方法:

                                        使用focusout 的“问题”是,如果对话框/模态/菜单中的某个元素失去焦点,那么“内部”的某个元素仍会触发该事件。我们可以通过查看event.relatedTarget(它告诉我们哪个元素将获得焦点)来检查情况是否如此。

                                        dialog = document.getElementById("dialogElement")
                                        
                                        dialog.addEventListener("focusout", function (event) {
                                            if (
                                                // we are still inside the dialog so don't close
                                                dialog.contains(event.relatedTarget) ||
                                                // we have switched to another tab so probably don't want to close 
                                                !document.hasFocus()  
                                            ) {
                                                return;
                                            }
                                            dialog.close();  // or whatever logic you want to use to close
                                        });
                                        

                                        上面有个小问题,那就是relatedTarget 可能是null。如果用户在对话框外部单击,这很好,但如果除非用户在对话框内部单击并且对话框碰巧不可聚焦,那么这将是一个问题。要解决此问题,您必须确保设置 tabIndex=0 以便您的对话框具有焦点。

                                        【讨论】:

                                        • 这是迄今为止最好的解决方案,因为它考虑了可访问性。
                                        【解决方案27】:

                                        这是我对这个问题找到的最简单的答案:

                                        window.addEventListener('click', close_window = function () {
                                          if(event.target !== windowEl){
                                            windowEl.style.display = "none";
                                            window.removeEventListener('click', close_window, false);
                                          }
                                        });
                                        

                                        您会看到我将函数命名为“close_window”,以便在窗口关闭时删除事件侦听器。

                                        【讨论】:

                                          【解决方案28】:

                                          一种用纯 JavaScript 编写的方法

                                          let menu = document.getElementById("menu");
                                          
                                          document.addEventListener("click", function(){
                                              // Hide the menus
                                              menu.style.display = "none";
                                          }, false);
                                          
                                          document.getElementById("menuscontainer").addEventListener("click", function(e){
                                              // Show the menus
                                              menu.style.display = "block";
                                              e.stopPropagation();
                                          }, false);
                                          

                                          【讨论】:

                                            【解决方案29】:

                                            您不需要(太多)JavaScript,只需要 :focus-within 选择器:

                                            • 使用.sidebar:focus-within 显示您的侧边栏。
                                            • 在您的侧边栏和正文元素上设置tabindex=-1 以使它们具有焦点。
                                            • 使用sidebarEl.focus()document.body.focus() 设置侧边栏可见性。

                                            const menuButton = document.querySelector('.menu-button');
                                            const sidebar = document.querySelector('.sidebar');
                                            
                                            menuButton.onmousedown = ev => {
                                              ev.preventDefault();
                                              (sidebar.contains(document.activeElement) ?
                                                document.body : sidebar).focus();
                                            };
                                            * { box-sizing: border-box; }
                                            
                                            .sidebar {
                                              position: fixed;
                                              width: 15em;
                                              left: -15em;
                                              top: 0;
                                              bottom: 0;
                                              transition: left 0.3s ease-in-out;
                                              background-color: #eef;
                                              padding: 3em 1em;
                                            }
                                            
                                            .sidebar:focus-within {
                                              left: 0;
                                            }
                                            
                                            .sidebar:focus {
                                              outline: 0;
                                            }
                                            
                                            .menu-button {
                                              position: fixed;
                                              top: 0;
                                              left: 0;
                                              padding: 1em;
                                              background-color: #eef;
                                              border: 0;
                                            }
                                            
                                            body {
                                              max-width: 30em;
                                              margin: 3em;
                                            }
                                            <body tabindex='-1'>
                                              <nav class='sidebar' tabindex='-1'>
                                                Sidebar content
                                                <input type="text"/>
                                              </nav>
                                              <button class="menu-button">☰</button>
                                              Body content goes here, Lorem ipsum sit amet, etc
                                            </body>

                                            【讨论】:

                                              猜你喜欢
                                              • 2016-07-10
                                              • 1970-01-01
                                              • 2018-12-11
                                              相关资源
                                              最近更新 更多