在外部设置显示样式会导致onclick()事件两次单击以初始化

时间:2016-11-05 00:27:38

标签: javascript html css

为什么我们必须在HTML上设置display: none;内联,而不是在外部设置onclick()事件才能在第一次点击时工作。

在外部设置代码工作但是初始化了两次,一次设置事件处理程序,另一次触发事件处理程序。我的代码

function submenu() {
  Menu = document.getElementById('menu');
  sub = document.getElementById('sub');

  function display() {
    if (sub.style.display === 'none') {
      sub.style.display = "inline-block";
    } else {
      sub.style.display = "none";
    }
  }
  Menu.addEventListener('click', display);
}

function pageLoad() {
  submenu();
}
nav {
  position: relative;
  margin: 0 auto;
  top: -60%;
  left: 24%;
  display: block;
  width: 33%;
  height: 20%;
}

nav ul {
  list-style-type: none;
  width: 100%;
  display: block;
}

nav ul li {
  width: 100%;
  color: #888;
  z-index: 0;
  display: block;
  font-size: 1.5em;
}

nav ul li a {
  text-decoration: none;
  color: #888;
}

#sub {
  width: 120%;
  position: absolute;
  top: 230%;
  z-index: 1;
  display: none;
  background-color: rgba(51, 51, 51, 0.8);
  margin: 0 auto;
}

#sub li {
  margin-top: 3px;
  padding: 2px;
  width: 100%;
  opacity: 2;
}
<nav>
  <ul>
    <li id="menu"> - Menu - </li>
    <ul id="sub">
      <li><a href="#methods">Services</a></li>
      <li><a href="#aftercare">Aftercare</a></li>
      <li><a href="#about">About Me</a></li>
      <li><a href="#contact">Contact Me</a></li>
    </ul>
    </li>
  </ul>
</nav>

初始化然后工作需要两次点击,但在更改以下行之后,每次都会首先点击:

HTML更改:

<nav id="menu">
<ul id="sub" style="display: none;">

CSS更改:

#sub {
        width: 120%;
        position: absolute;
        top: 230%;
        z-index: 1;
        background-color: rgba(51,51,51,0.8);
        margin: 0 auto;
    }

对于javascript代码,我将函数添加到window.onload,如:

window.onload = pageLoad;
function pageLoad() {
    submenu();
}

因此,除非我将样式display: none;更改为内联CSS,否则仍需要两次点击。 我想更好地理解为什么会发生这种情况所涉及的过程。我曾尝试在谷歌上寻找这个解释,但一无所获。

1 个答案:

答案 0 :(得分:1)

如果您在CSS中设置GET /add controllers.Application.add() POST /create controllers.Application.create() GET /add2 controllers.Application.add2() POST /create2 controllers.Application.create2() 的样式,那么从display开始将是一个空字符串,但是如果您使用style属性在元素上设置它,那么它将有你给它的价值。您可以通过检查值是否为空字符串来解决这个问题,但是您必须弄清楚这对您的应用程序意味着什么(基于CSS中的初始值)。

我想在这里提出一个替代方案,它也可以很好地为其他方案服务,并且不要求你改变style属性,而是依赖于改变元素的类。

如果您要添加一些CSS以默认隐藏子菜单,并且可以将一个类切换为可见的菜单:

sub.style.display

使用以下JS切换类

nav ul ul { 
    display: none; 
}
nav .active {
    display: block;
}

通过这种方式,您可以轻松调整代码,以便为多个子菜单执行此操作,因此这是另一个稍微更通用的示例,允许您拥有多个菜单和子菜单。

e.g。

HTML

var menu = document.getElementById('menu');
var sub = document.getElementById('sub');
function toggleMenu(){
    sub.classList.toggle('active');
}
menu.addEventListener('click', toggleMenu);

CSS

<nav class="menu">
    <ul>
        <li class="parent"> - Menu 1 -
            <ul>
                <li><a href="#sub">sub menu 1</a></li>
                <li><a href="#sub">sub menu 1</a></li>
            </ul>
        </li>
        <li class="parent"> - Menu 2 -
            <ul>
                <li><a href="#sub">sub menu 2</a></li>
                <li><a href="#sub">sub menu 2</a></li>
            </ul>
        </li>
    </ul>
</nav>

JS

.menu ul ul { display: none; }
.menu .active {
    display: block;
}