【问题标题】:How Do I Get Multiple Functions to Work onclick for a Button?如何让多个功能在单击按钮时起作用?
【发布时间】:2018-11-20 22:21:42
【问题描述】:

我正在尝试创建一个在单击时执行两件事的按钮。首先,在汉堡菜单图标和时间图标 (X) 之间切换。第二个动作是将侧边导航元素的宽度从 0px 更改为 250px,然后如果再次单击则返回 0px(与汉堡菜单从和 X 切换并返回到汉堡包同步)。我已经能够让这些动作的各个部分发挥作用,但无法将它们全部组合在一起。以下是我目前拥有的功能:

<script>

     document.getElementById("test").addEventListener("click", myFunctionTwo);

    function myFunctionTwo() {
        document.getElementById("mySidenav").style.width = "250px";
    }    

    function myFunction(x) {
      x.classList.toggle("fa-times");       
      x.classList.toggle("fa-bars");     
    }

    </script>

HTML:

<button id="test">
<i onclick="myFunction(this)" class="fa fa-bars"></i>    
</button>        

<div id="mySidenav" class="sidenav">    
<a href="#">NFL</a>
<a href="#">NBA</a>
<a href="#">MLB</a>   
</div>

有些东西告诉我,我的 i 元素的 onclick 函数应该与我的按钮的事件侦听器结合使用,但我无法让它正常工作。如果再次单击该按钮,我还需要添加一种方法将 sidenav 隐藏回 0px 宽度。

做这样的事情的正确方法是什么?

提前感谢您的帮助!

【问题讨论】:

  • 要处理多个函数,请创建一个新函数,按顺序执行这两个函数。并将新函数绑定为处理程序。
  • addEventListener 的优点是您可以多次调用它来添加多个事件处理程序。

标签: javascript onclick addeventlistener htmlbutton


【解决方案1】:

尝试将这两个函数组合成一个回调。这只是为了让您入门。

document.getElementById("test").addEventListener("click", myFunction);

function myFunctionTwo(open) {
    if(open){
      document.getElementById("mySidenav").style.width = "250px";
    }else{
      document.getElementById("mySidenav").style.width = "0px";
    }
}    

function myFunction(event) {//have myFunction queue the work for everything that needs to be done.
  if(! event.currentTarget.opened){
    event.currentTarget.opened = true;
    myFunctionTwo(true);
  }else{
    event.currentTarget.opened = false;
    myFunctionTwo(false);
  }

  var x = event.currentTarget.children[0];
  x.classList.toggle("fa-times");       
  x.classList.toggle("fa-bars");     
}
#mySidenav{
  width:0px;
  overflow:hidden;
  border:1px solid #333;
}
#test{
  width:20px;
  height:20px;
}
<button id="test">
<i class="fa fa-bars"></i>    
</button>        

<div id="mySidenav" class="sidenav">    
<a href="#">NFL</a>
<a href="#">NBA</a>
<a href="#">MLB</a>   
</div>

【讨论】:

  • 感谢您的回复!我对结合这两个功能的意思有点困惑。当我实施您的解决方案时,它几乎可以完美运行。唯一的问题是,如果您直接单击图标,则图标不会改变。但是,如果您单击按钮的其他区域,则可以。我尝试将图标切换添加到 myFunctionTwo 中,但我破坏了功能......
  • 通过结合这两个函数,我的意思是您只需将一个事件处理程序绑定到点击事件,然后从该函数中获得所有逻辑流程。在这种情况下,我直接在处理程序中保留了 classList 切换,但您可以想象有一个 function clickhandler(event) 依次调用 myFunction()myFunctionTwo()。至于为什么当你直接点击它时图标没有改变......我搞砸了,留下了应该删除的&lt;i onclick="myFunction(this)" ......。我的错。我会编辑答案
  • 澄清一下,在 sn-p 中使用 onclick 的问题是导致代码执行两次,一次用于图标上的单击处理程序,然后在事件冒泡时再次执行按钮。如果您不清楚事件冒泡是如何工作的,那么它在 JS 中是一个非常有用(且重要)的概念,您应该阅读它。但基本上一个事件会遍历每个父母“冒泡”到身体。所以这就是代码执行两次的方式,导致图标切换两次(回到它的初始状态)
  • 感谢您的回复!我只是阅读了一些关于 JS 冒泡的内容,因为我对它一点也不熟悉。对我来说,为什么 onclick sn-p 导致代码执行两次而不是一次是有道理的。但是,即使在从图标元素中删除了 sn-p 之后,如果我单击图标之外的按钮上的其他位置,我仍然只能切换图标。到目前为止,您已经做得足够多了,但是如果您可以给我更多建议,我们将不胜感激!非常感谢!
  • @mizDawg 这又是我的错……我觉得很尴尬……应该是event.currentTarget,而不是event.target。 target 将是事件的发起者(在这种情况下,图标没有子元素),currentTarget 将是评估上下文(当前绑定在冒泡中的内容)。我会更正我的答案
【解决方案2】:

我会尝试这样的事情,让 CSS 为你处理更多。

document.getElementById("test").addEventListener("click", toggleNav);

function toggleNav()
{
  var body = document.getElementsByTagName("BODY")[0];
  body.classList.toggle('nav-open');
}    
body div#mySidenav {
  display:none;
  width:150px;
  background:yellow;
}
body button#test .fa-times {
	display:none;
}
body.nav-open button#test .fa-times {
	display:inline;
}
body.nav-open button#test .fa-bars {
	display:none;
}
body.nav-open div#mySidenav {
	display:block;
}
<html>
<body>

<button id="test">
<i class="fa fa-bars">-</i> 
<i class="fa fa-times">x</i>
</button>        

<div id="mySidenav" class="sidenav">    
<a href="#">NFL</a>
<a href="#">NBA</a>
<a href="#">MLB</a>   
</div>

</body>
</html>

<body>

<button id="test">
<i class="fa fa-bars"></i> 
<i class="fa fa-times"></i>
</button>        

<div id="mySidenav" class="sidenav">    
<a href="#">NFL</a>
<a href="#">NBA</a>
<a href="#">MLB</a>   
</div>

</body>

【讨论】:

    【解决方案3】:

    您可以尝试关注

    function myFunction(x) {
      x.classList.toggle("fa-times");
      x.classList.toggle("fa-bars");
      document.getElementById("mySidenav").classList.toggle("width_250px");
    }
    .sidenav {
      width: 0px;
    }
    
    .width_250px {
      width: 250px;
    }
    <i onclick="myFunction(this)" class="fa fa-bars">Toggle</i>
    
    <div id="mySidenav" class="sidenav">
      <a href="#">NFL</a>
      <a href="#">NBA</a>
      <a href="#">MLB</a>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多