【问题标题】:jQuery: How to make clicking anywhere outside of left menu close said window?jQuery:如何使单击左侧菜单之外的任何位置关闭所述窗口?
【发布时间】:2015-06-14 03:02:09
【问题描述】:

我的网站左侧有一个菜单按钮正在进行中。

这是打开菜单的 Javascript 代码:

var main = function()
$('.icon-menu').click(function() {
    $('.menu').animate({
        left: "0px"
    }, 400);
    $('body').animate({
        left: "285px"
    }, 400);
});

这是关闭菜单的 Javascript 代码:

$('.icon-close').click(function () {
    $('.menu').animate({
        left: "-285px"
    }, 400);
    $('body').animate({
        left: "0px"
    }, 400);
});

我希望能够做的是,而不是使用“关闭”图标,我希望单击页面上的任意位置(包括原始菜单按钮)来关闭菜单。

由于当前编写的代码,当菜单打开/关闭时,它从左侧滑入,页面主体向右滑动相同数量的像素,关闭时反之亦然。

编辑:

这是所要求的 HTML 框架:

<div class="menu">
    <div class="icon-close">
        <img src="close.png">
    </div>
    <ul>
        <li><a href="home.html">Home</a>
        </li>
        <li><a href="home.html">Gallery</a>
        </li>
        <li><a href="home.html">Locations</a>
        </li>
        <li><a href="home.html">Contact Us</a>
        </li>
    </ul>
</div>
<div class="jumbotron">
    <div class="icon-menu">
        <i class="fa fa-bars"></i>Menu
    </div>
</div>

【问题讨论】:

标签: javascript jquery html css


【解决方案1】:

您可以捕获一个 document.onclick 事件,然后根据一组允许的 id 来检查事件目标 id 请注意,要执行此操作,您必须将 id 属性添加到关闭按钮和“正文”。我还冒昧地在菜单中添加了一个 id,并在文档的“正文”周围添加了一个包装器,并将您的 body 标记动画更改为该包装器,因为您不应该直接移动 body 标记。请注意,要在菜单打开时调整正文大小,只需更改正文 position: absolute 并设置 right: 0px;

(Demo在菜单打开时保持身体大小)

(Demo调整主体大小以保持在菜单打开时的视口内)

$(document).on('click', function(e) {
  if ($("#menu").position().left != '0') {
    if (e.target.id === "open") {
      $('#menu').animate({
        left: "0px"
      }, 400);
      $('#body').animate({
        left: "285px"
      }, 400);
    }
  } else {
    if (e.target.id === "body" || e.target.id === "close" || e.target.id === "open") {
      $('#menu').animate({
        left: "-285px"
      }, 400);
      $('#body').animate({
        left: "0px"
      }, 400);
    }
  }
});
html, body, #menu, #body {
  height: 100%;
}
.menu {
  position: absolute;
  width: 285px;
  left: -285px;
}
#body {
  position: relative;
  left: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu" id="menu">
  <div class="icon-close">
    <img src="close.png" id="close">
  </div>
  <ul>
    <li><a href="#">Home</a>
    </li>
    <li><a href="#">Gallery</a>
    </li>
    <li><a href="#">Locations</a>
    </li>
    <li><a href="#">Contact Us</a>
    </li>
  </ul>
</div>
<div id="body">
  <div class="jumbotron">
    <div class="icon-menu" id="open">
      <i class="fa fa-bars" id="open"></i>Menu
    </div>
  </div>
</div>

纯 JS 和 CSS

下面是实现同样效果的纯javascript和css方法。我将其包含在内以供参考,因为它比包含 jquery 的重量轻得多,但是如果您已经包含 jquery,则没有理由不使用 jquery 方法。请注意,在不支持 css 过渡的旧浏览器上,菜单仍会打开但不会动画(这对旧浏览器来说是一件好事,因为 javascript 动画会减慢速度)

(Demo在菜单打开时保持身体大小)

Demo 调整主体大小以保持在菜单打开时的视口内)

var menu = document.getElementById("menu");
var body = document.getElementById("body");
menu.style.transition = "0.3s linear";
body.style.transition = "0.3s linear";
document.onclick = function(e) {
  if (menu.style.left != "0px") {
    if (e.target.id === "open") {
      menu.style.left = "0px";
      body.style.left = "285px";
    }
  } else {
    if (e.target.id === "body" || e.target.id === "close" || e.target.id === "open") {
      menu.style.left = "-285px";
      body.style.left = "0px";
    }
  }
};
html, body, #menu, #body {
  height: 100%;
}
.menu {
  position: absolute;
  width: 285px;
  left: -285px;
}
#body {
  position: relative;
  left: 0px;
}
<div class="menu" id="menu">
  <div class="icon-close">
    <img src="close.png" id="close">
  </div>
  <ul>
    <li><a href="#">Home</a>
    </li>
    <li><a href="#">Gallery</a>
    </li>
    <li><a href="#">Locations</a>
    </li>
    <li><a href="#">Contact Us</a>
    </li>
  </ul>
</div>
<div id="body">
  <div class="jumbotron">
    <div class="icon-menu" id="open">
      <i class="fa fa-bars" id="open"></i>Menu
    </div>
  </div>
</div>

【讨论】:

  • 嘿,只是想感谢您的 cmets。我知道我需要更多的逻辑,老实说,我急忙回答。我不应该发布不完整的答案,而且您的 cmets 非常有帮助;非常感谢您甚至发表评论的事实!恐怕这可能会被标记为无用的评论,所以我会尝试添加一些有用的东西:你的脚本很棒,但也许你可以添加一些过滤,这样当你点击菜单时,只有关闭按钮会关闭它?我认为这是预期的功能。不过,如果我错了,请纠正我(就像你所做的那样!哈哈)。
  • 事实上,我不希望关闭按钮成为关闭菜单的唯一按钮,这正是我想要的,谢谢@humble.rumble.6x3!
  • @humble.rumble.6x3 很高兴我的思维方式对您有所帮助!另外,如果您阅读了我的最后一条评论,在我测试了两种方法之后,您在技术上都对我想要的东西是正确的。你们都只关注两个不同的方面,我有点需要一个混合体。
  • 在我的例子中你可以做$('.menu, body').animate如果你真的想为整个身体设置动画(你必须将身体的位置设置为relative),只是指出这一点,但我认为这是一个将您的主要内容放在菜单旁边的一个大 div 中是更好的主意。无论哪种方式,这绝对值得成为答案。不过有一件事,我同意 CSS 动画真的很酷,但浏览器支持还不是很好,你必须确保包含供应商前缀。
【解决方案2】:

以下是 sn-p 的简陋版本:

http://jsfiddle.net/humbleRumble/3j7s9ggz/

您可以将一个单击事件绑定到与单击关闭按钮执行相同操作的文档:

$(document).on('click', function (e) {
    // Filter some elements out so that this function doesn't
    // execute when it's not intended to.
    var target = e.target,
        isMenuElem = $(target).parents('.menu').length || $(target).is('.menu'),
        isMenuClose = $('.icon-close').has(target).length,
        isIconMenu = $(target).is('.icon-menu');
    // Simply return if the clicked element falls under the filter.
    // This allows the close button to close,
    // the menu to not close itself if you click its body,
    // the function to not interfere with the menu button functionality,
    // and that a click on anywhere will close the menu.
    if (isMenuElem && !isMenuClose || isIconMenu) return;
    $('.menu, #jumbotron').animate({
        left: "-285px"
    }, 400);
});

$('.icon-menu').click(function () {
    // This is a 'toggle' value for left,
    // if the menu is opened (left: 0), close it (left: -285)
    // and vice-versa.
    var toggleAnim = $('.menu').css('left') === '-285px' ? 0 : '-285px';
    $('.menu, #jumbotron').animate({
        // Apply the toggle
        left: toggleAnim
    }, 400);
});
html, body {
    padding: 0;
    margin: 0;
}
#jumbotron {
    position: relative;
    height: 500px;
    width: 300px;
    float: left;
}
.menu {
    position: relative;
    width: 285px;
    height: 500px;
    background: red;
    float: left;
}
.icon-menu {
    background: black;
    color: #fff;
    cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu">
    <div class="icon-close">
        <img src="close.png" alt="Close Me">
    </div>
    <ul>
        <li><a href="home.html">Home</a>
        </li>
        <li><a href="home.html">Gallery</a>
        </li>
        <li><a href="home.html">Locations</a>
        </li>
        <li><a href="home.html">Contact Us</a>
        </li>
    </ul>
</div>
<div class="jumbotron" id="jumbotron">
    <div class="icon-menu">
        <i class="fa fa-bars"></i>Menu
    </div>
</div>

这将通过点击页面上的任意位置触发,但不会触发菜单内的元素(关闭按钮除外)。

【讨论】:

  • 谢谢。但是,如果您单击菜单按钮太快,它似乎会出现故障。无论哪种方式,都会将其包含在我的帖子中。
猜你喜欢
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 2019-06-30
  • 2020-07-08
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
相关资源
最近更新 更多