jQuery点击侦听器调用为时过早

时间:2018-07-25 13:07:14

标签: javascript jquery

我有两种简单的方法,一种是打开菜单,另一种是关闭菜单。

在按钮上单击openmenu方法。然后,我想在菜单右侧的所有内容中添加一个单击侦听器,并包装在一个称为包装器的div中。仅在菜单打开时添加它,以便可以关闭。但是,由于打开菜单按钮位于称为“包装器”的div内部,因此它会立即打开和关闭。

我要打开菜单,然后在打开菜单时先听一下它的点击,所以不要计算它打开时的第一次点击。

下面是我的代码。

function openMenu() {
    document.getElementById("sideMenu").style.width = "250px";
    menuOpen = true;

    $("#wrapper").one('click',function(){
       closeMenu();
    });
}

function closeMenu() { //method to close the menu
    document.getElementById("sideMenu").style.width = "0"; //set the width of the menu to 0
    menuOpen=false; //the menu isn't open anymore
    alert();
}

4 个答案:

答案 0 :(得分:1)

您可以阻止wrapper传播到wrapper。这样可以阻止事件冒泡,并且不会调用function openMenu(e) { e.stopPropagation(); document.getElementById("sideMenu").style.width = "250px"; menuOpen = true; $("#wrapper").one('click',function(){ closeMenu(); }); } 上的任何事件侦听器。

{{1}}

Reference: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

答案 1 :(得分:0)

您应该重新排列HTML,以使openmenu按钮位于wrapper div之外。

编辑: 然后尝试这个。

$("#wrapper button").click(function() {
    if (menuOpen)
        closeMenu();
    else
        openMenu();
}

function openMenu() {
    document.getElementById("sideMenu").style.width = "250px";
    menuOpen = true;    
}

function closeMenu() { //method to close the menu
    document.getElementById("sideMenu").style.width = "0"; //set the width of the menu to 0
    menuOpen=false; //the menu isn't open anymore    
}

答案 2 :(得分:0)

打开菜单的click事件冒泡到#wrapper元素,触发closeMenu函数。您可以通过在点击事件上使用.stopPropagation()或通过从处理程序返回false来防止这种情况:

function openMenu() {
  document.getElementById("sideMenu").style.width = "250px";

  $("#wrapper").one('click', closeMenu);
  return false; // <-- prevent the click event from bubbling up to #wrapper
}

function closeMenu() { 
  document.getElementById("sideMenu").style.width = "0"; 
}

$('#openTheMenu').on("click", openMenu);
#sideMenu {
  border: 1px solid;
  overflow: hidden;
  width: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
  <div id="sideMenu">This is the side menu</div>
  <button id="openTheMenu">Open</button>
</div>

答案 3 :(得分:0)

好吧,让我们看看。选项,选项,这么多选项!基本的:

1。打开测试

测试事务状态以确定菜单的当前状态,并在不满足条件的情况下纾困:

function openMenu() {

    $("#sideMenu").css("width", "250px");

    $("#wrapper").on('click', function(){
       closeMenu();
    });
}

function closeMenu() { //method to close the menu
    let $sMenu = $("#sideMenu")
    if($sMenu.css("width") !== "250px") return false;
    $sMenu.css("width" "0px"); //set the width of the menu to 0
}

2。附加一个类[[注意:这是我的首选方法,或下面#3的混合方法]]

由于您始终使用jQuery处理定位,因此请完全删除宽度代码,这有利于CSS既维护MVC又进行提升。打开时追加该类,然后使用类名作为目标,将其剥离以关闭。

jQuery

$("#wrapper").on('click', function(){
   closeMenu();
});

function openMenu(){
   $("#sideMenu").addClass("menuOpen"); 
}

function closeMenu(){
   $(".menuOpen").removeClass("menuOpen"); // Note that this can ONLY TARGET the menu WHEN OPEN 
}

CSS

#sideMenu { width:0px; }
#sideMenu.menuOpen { width: 250px; }

3。不要使用单独的方法

使用单个函数来处理两个事件:

function toggleMenu(forceState=null){
    let $sMenu = "(#sideMenu)";
    if(forceState !== null){ 
        $sMenu.css('width', forceState);
        return;
    }

    let currentMenuWidth = $menuObj.css('width');
    $sMenu.css("width", ($menuObj)=>{return currentMenuWidth=='250px' ? '0px' : '250px');
}

旁注: Hide / Show 如果您坚持使用jQuery,请利用它。它内置了hide()show()方法。更好的是,使用.toggle()https://www.w3schools.com/jquery/eff_toggle.asp