【问题标题】:twitter bootstrap dropdown doesn't toggle closed when it shouldtwitter bootstrap 下拉菜单在应该关闭时不会关闭
【发布时间】:2012-08-25 17:06:15
【问题描述】:

哦,伙计,我一直在为此扯头发。 4 小时的下拉菜单。

我正在使用 Twitter Bootstrap。

顶部的固定导航有一个下拉菜单,非常标准。

除了下拉菜单没有正常关闭。它只会在按下切换本身时切换打开和关闭,而不是在按下菜单中的项目或用户在菜单外单击时(这两者都应该关闭下拉菜单)。

我唯一不标准的做法是使用 iframe 和 bootswatch 中的主题。

我以前没有遇到过这样的问题,所以我觉得这可能是一个错误(今天将 bootstrap 升级到 2.1.0,jquery 升级到 1.7.2)。

这里的所有代码:

    <!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>test</title>
        <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
        <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
        <!-- Le styles -->
        <link href="./css/bootstrap.css" rel="stylesheet">
        <style>
            iframe {
                border: 0px;
                height: 95%;
                left: 0px;
                position: absolute;
                top: 50px;
                width: 100%;
            }
        </style>
    </head>
    <body>
        <div class="navbar navbar-fixed-top">
            <div class="navbar-inner">
                <div class="container">
                    <a class="brand" target="mainframe" href="./home.html">
                       Brand
                    </a>
                    <ul class="nav">
                        <li class="dropdown">
                            <a href="#" class="dropdown-toggle" role="button" data-toggle="dropdown">
                                <i class="icon-pencil icon-white"></i>
                                Sample
                                <b class="caret"></b>
                            </a>
                            <ul class="dropdown-menu" role="menu">
                                <li>
                                    <a target="mainframe" href="./home.html#">One</a>
                                </li>
                                <li>
                                    <a target="mainframe" href="./home.html#">Two</a>
                                </li>
                                <li>
                                    <a target="mainframe" href="./home.html#">Three</a>
                                </li>
                                <li>
                                    <a target="_blank" href="#">Four
                                        <i class="icon-share-alt"></i>
                                    </a>
                                </li>
                                <li>
                                    <a target="_blank" href="#">Five
                                        <i class="icon-share-alt"></i>
                                    </a>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <a href="#">
                                <i class="icon-certificate icon-white"></i>Stuff</a></li>
                        <li>
                            <a href="#">
                                <i class="icon-globe icon-white"></i>Things</a></li>
                        <li>
                            <a target="mainframe" href="./home.html">
                                <i class="icon-film icon-white"></i>Nothing</a></li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container">
            <iframe id="frame" name="mainframe" src="./home.html"></iframe>
            <!-- /container -->
        </div>
        <!-- Le javascript==================================================-->
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>

        <script src="./js/bootstrap.js"></script>
        <script type="text/javascript">
            $(document).ready(function () {
                $('.dropdown-toggle').dropdown();
                var frameheight = window.innerHeight - 50;
                document.getElementById("frame").style.height = frameheight + "px";
            });

            $(window).resize(function () {
                var frameheight = window.innerHeight - 50;
                document.getElementById("frame").style.height = frameheight + "px";
            });
        </script>
    </body>
</html>

住在这里: http://www.joshlevent.com/dropdownbug/

【问题讨论】:

  • 只是一个建议 - 尝试使用 jQuery1.7.2
  • 感谢@aravind,我之前都尝试过,只是不小心把它留在了 1.7.1 上。现在回到 1.7.2。

标签: jquery iframe drop-down-menu twitter-bootstrap bootswatch


【解决方案1】:

默认情况下,iframe 不会将点击事件传播到其父级。您需要手动添加代码来执行此操作。除了能够编辑您正在加载的 iframe 的内容之外,跨域限制还要求您从与您的页面相同的域加载 iframe 内容。

这需要从 in iframe 页面运行:

$('html').on('click', function () {
  parent.$('#frame').trigger('click');
});

#frame 是您的 iframe 的 ID。您可以将点击委托给父级中的任何内容(例如,'body'),这也可以。取决于您希望 iframe 中的内容与页面的耦合程度。

所以,这应该负责关闭菜单的页面。

重要更新

至于点击菜单项关闭菜单,显然在最新的更新(2.0.4 > 2.1.0)中有一个错误[?]:Dropdown menus don't get closed when selecting an option。选择器已从 '.dropdown form' 更改为 '.dropdown',因此,曾经让表单中的下拉菜单更容易使用的著名功能现在演变为阻止所有下拉菜单项点击的回调。

临时解决方案是在错误修复 (2.1.1) 之前包含以下代码:

$('body')
  .off('click.dropdown touchstart.dropdown.data-api', '.dropdown')
  .on('click.dropdown touchstart.dropdown.data-api'
    , '.dropdown form'
    , function (e) { e.stopPropagation() })

【讨论】:

  • 即使这样似乎也不适用于跨域 iframe。检查stackoverflow.com/a/5083086/1478467
  • @Sherbrow 是的,你是对的!我添加了一点关于需要具有相同来源的说明。
  • 完美。感谢您的指点。我能够用这个解决整个问题。将在下面发布已解决的 HTML 作为新答案。
  • @Josh 我做了更多研究并更新了我的答案。我认为我添加的解决方案比切换到按钮标记要好得多,因为它可以让您轻松地将代码迁移到未来的版本,而无需重构您的标记。
【解决方案2】:

没有什么对我有用,除了这个:

$('.dropdown-menu li a').on('click', function(e) {
    $('.dropdown-toggle').dropdown('toggle');
    e.stopPropagation();
});

【讨论】:

    【解决方案3】:

    我在 2.1.1 中看到了同样的问题。

    在 GitHub 上发布的对我来说很容易工作的解决方案是:

    $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); });

    感谢 blakeembrey,https://github.com/twitter/bootstrap/issues/5094

    【讨论】:

      【解决方案4】:

      这是我根据 merv 的出色回答实施的完整解决方案。如果有更好的方法让我为将来的人发布解决方案,请告诉我。

      这个jquery被添加到框架中页面的html底部:

      $('html').on('click', function () {
        parent.$('#frame').trigger('click');
      });
      

      下拉菜单已切换为按钮并重新设置样式以适应导航栏。在html中:

                      <li class="btn-group" id="samplebtn">
                          <a href="#" class="btn btn-primary dropdown-toggle" role="button" data-toggle="dropdown">
                              <i class="icon-pencil icon-white"></i>
                              Sample
                              <b class="caret"></b>
                          </a>
      

      在 CSS 中:

              #samplebtn {
              position:absolute;
              top: 0;
              margin: 0px;
              padding: 0px;
              border: 0px;
              }
              #samplebtn .btn {
                  border: 0px;
              }
      

      解决方案的完整代码(更新问题中的完整代码 - 这只是外部框架):

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="utf-8">
              <title>test</title>
              <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
              <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
              <!-- Le styles -->
              <link href="./css/bootstrap.css" rel="stylesheet">
              <style>
                  iframe {
                      border: 0px;
                      height: 95%;
                      left: 0px;
                      position: absolute;
                      top: 50px;
                      width: 100%;
                  }
                  #samplebtn {
                  position:absolute;
                  top: 0;
                  margin: 0px;
                  padding: 0px;
                  border: 0px;
                  }
                  #samplebtn .btn {
                      border: 0px;
                  }
              </style>
          </head>
          <body>
              <div class="navbar navbar-fixed-top">
                  <div class="navbar-inner">
                      <div class="container">
                          <a class="brand" target="mainframe" href="./home.html">
                             Brand
                          </a>
                          <ul class="nav">
      
                              <li class="btn-group" id="samplebtn">
                                  <a href="#" class="btn btn-primary dropdown-toggle" role="button" data-toggle="dropdown">
                                      <i class="icon-pencil icon-white"></i>
                                      Sample
                                      <b class="caret"></b>
                                  </a>
                                  <ul class="dropdown-menu" role="menu">
                                      <li>
                                          <a target="mainframe" href="./home.html#">One</a>
                                      </li>
                                      <li>
                                          <a target="mainframe" href="./home.html#">Two</a>
                                      </li>
                                      <li>
                                          <a target="mainframe" href="./home.html#">Three</a>
                                      </li>
                                      <li>
                                          <a target="_blank" href="#">Four
                                              <i class="icon-share-alt"></i>
                                          </a>
                                      </li>
                                      <li>
                                          <a target="_blank" href="#">Five
                                              <i class="icon-share-alt"></i>
                                          </a>
                                      </li>
                                  </ul>
                              </li>
                              <li>
                                  <a href="#">
                                      <i class="icon-certificate icon-white"></i>Stuff</a></li>
                              <li>
                                  <a href="#">
                                      <i class="icon-globe icon-white"></i>Things</a></li>
                              <li>
                                  <a target="mainframe" href="./home.html">
                                      <i class="icon-film icon-white"></i>Nothing</a></li>
                          </ul>
                      </div>
                  </div>
              </div>
              <div class="container">
                  <iframe id="frame" name="mainframe" src="./home.html"></iframe>
                  <!-- /container -->
              </div>
              <!-- Le javascript==================================================-->
              <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
      
              <script src="./js/bootstrap.js"></script>
              <script type="text/javascript">
                  $(document).ready(function () {
                      $('.dropdown-toggle').dropdown();
                      var frameheight = window.innerHeight - 50;
                      document.getElementById("frame").style.height = frameheight + "px";
                  });
      
                  $(window).resize(function () {
                      var frameheight = window.innerHeight - 50;
                      document.getElementById("frame").style.height = frameheight + "px";
                  });
      
                  $('.dropdown-menu').on('click', function () {
                    $('.dropdown-toggle').dropdown();
                  });
              </script>
          </body>
      </html>
      

      为了完整的参考,这是框架内页面的代码:

      <!DOCTYPE html>
      <html lang="en">
      
          <head>
              <meta charset="utf-8">
              <title>Title</title>
      
              <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
              <!--[if lt IE 9]>
                  <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
              <![endif]-->
              <!-- Le styles -->
              <link href="./bootstrap.min.css" rel="stylesheet">
              <style>
      
              </style>
          </head>
      
          <body onload="scrollTo(0,0); $('#loading').css('display','none');">
              <div id="loading" style="width: 100%; height: 100%; background-color: white; background-image:url('loader.gif'); background-repeat:no-repeat; background-position: center center; position:fixed; display: none; z-index:100;"></div>
              <script type="text/javascript">
                  document.getElementById("loading").style.display = 'block';
              </script>
      
      
              <div class="container">
              <div class="span12">
                          <h2>Project Description</h2>
                          <p>Lorem Ipsum Dolor Sit Amet</p>
      
      
                      </div>
      
                  <!-- /container -->
              </div>
              <!-- Le javascript==================================================-->
      
              <script src="./jquery.js"></script>
              <script src="./bootstrap.min.js"></script>
      <!--        <script src="./bootstrap-dropdown.js"></script>
      -->
      <script>
      $('html').on('click', function () {
        parent.$('#frame').trigger('click');
      });
      
      </script>
      
          </body>
      
      </html>
      

      修复了您可以预览的测试站点(但不要复制整个页面代码,因为其中包含一些服务器端 (cloudflare) 内容)。 http://www.joshlevent.com/dropdownbug/

      【讨论】:

        【解决方案5】:

        bug 已修复, 您可以使用 https://github.com/twitter/bootstrap/blob/2.1.1-wip/js/bootstrap-dropdown.js ,下拉列表的 2.1.1-wip

        【讨论】:

          【解决方案6】:

          当单击另一个时,您可以从下拉菜单中删除“打开”类。 到目前为止,这对我有用:

          $(document).ready(function () {
              $('a.dropdown-toggle').each(function(){
                  $(this).on("click", function () {
                      $('li.dropdown').each(function () {
                          $(this).removeClass('open');
                      });
                  });
              });
          });
          

          【讨论】:

            【解决方案7】:

            我对导航菜单中多个下拉菜单的修复: 其他解决方案对我不起作用

            $('.dropdown-toggle').on('click', function (e) {
                  $('.dropdown-toggle').each(function (i,elem) {
                      if (elem != e.target) $(elem.parentElement).removeClass('open');
                  });
            })
            

            【讨论】:

              【解决方案8】:

              您还可以使用此代码从父页面添加传播点击事件(为我修复了相同的问题):

              var myFrameContents = document.getElementById("frame").contentWindow.document;
              myFrameContents.body.addEventListener("click", function() {
                  document.body.click();
              });
              

              【讨论】:

              • 仅仅因为你可以使用 vanilla JS 来完成同样的事情并不意味着你应该,尤其是当 jQuery 已经加载时(根据OP)。
              猜你喜欢
              • 1970-01-01
              • 2023-03-10
              • 2015-12-04
              • 2014-09-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-12-31
              • 2013-08-20
              相关资源
              最近更新 更多