我正在根据youtube教程制作一个应用程序.我已经知道正确的解决方案是什么样子的,但我不知道为什么这样的代码不起作用.它只执行一次.我在浏览器中选中"Inspector",它显示第二个div得到了活动类,但第二次单击不起作用.

document.querySelector('.emoji').addEventListener('click', function() {
  document.querySelector('.open').classList.toggle('active');
  document.querySelector('.closed').classList.toggle('active');
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.emoji {
  text-align: center;
  font-size: 20rem;
  cursor: pointer;
  display: none;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.active {
  display: block;
}
<!-- emoji no evil ????
        emoji monkey ???? -->

<div class="emoji open active">????</div>
<div class="emoji closed">????</div>

现在为什么这个解决方案不起作用?

我认为我有两个元素与表情符号类,所以这应该是可行的.今天我try 创建计算器应用程序,但遇到了同样的问题.当我点击第一个按钮时,它才起作用.我知道正确的解决方案是:

    document.querySelector('.open').addEventListener('click', function () {
      document.querySelector('.open').classList.toggle('active');
      document.querySelector('.closed').classList.toggle('active');
    });
    
    document.querySelector('.closed').addEventListener('click', function () {
      document.querySelector('.closed').classList.toggle('active');
      document.querySelector('.open').classList.toggle('active');
    });

但我不明白为什么第一个解决方案是错误的.请你解释一下.

推荐答案

document.querySelector只返回一个元素,这是与 Select 器匹配的第一个元素.

解决该问题的一种方法是将这两个元素包装到一个容器中,并监听对该元素的单击:

document.querySelector('.emoji-toggle').addEventListener('click', function() {
  document.querySelector('.open').classList.toggle('active');
  document.querySelector('.closed').classList.toggle('active');
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.emoji {
  text-align: center;
  font-size: 20rem;
  cursor: pointer;
  display: none;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.active {
  display: block;
}
<div class="emoji-toggle">
<div class="emoji open active">????</div>
<div class="emoji closed">????</div>
</div>

或使用事件委派:

document.addEventListener('click', function(e) {
  if (e.target.matches('.emoji')) {
    document.querySelector('.open').classList.toggle('active');
    document.querySelector('.closed').classList.toggle('active');
  }
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.emoji {
  text-align: center;
  font-size: 20rem;
  cursor: pointer;
  display: none;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.active {
  display: block;
}
<div class="emoji open active">????</div>
<div class="emoji closed">????</div>

如果它是一个复选框,您可能希望使用第一种方法.

根据您想做什么,您甚至不需要JavaScript:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.emoji {
  text-align: center;
  font-size: 20rem;
  cursor: pointer;
  display: none;
}

#mycheckbox:checked + label .open {
   display: block;
}

#mycheckbox:not(:checked) + label .closed {
   display: block;
}

#mycheckbox {
   display: none;
}


body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
<input type="checkbox" id="mycheckbox">
<label for="mycheckbox">
  <div class="emoji open">????</div>
  <div class="emoji closed">????</div>
</label>

如果您处理input元素、 Select 器和label元素的放置,并利用过渡和动画,您可以在不使用任何JavaScript的情况下执行移动菜单、不同字体大小和 colored颜色 主题的切换.

Javascript相关问答推荐

Flutter:显示PDF和视频,但阻止下载

在JavaScript中打开和关闭弹出窗口

在分区内迭代分区

通过在页面上滚动来移动滚动条

角色 map 集/spritebook动画,用户输入不停止在键上相位器3

将2D数组转换为图形

Regex结果包含额外的match/group,只带一个返回

在JS中拖放:检测文件

在使用HighChats时如何避免Datatables重新初始化错误?

ChartJs未呈现

Webpack在导入前混淆文件名

在FAQ Accodion应用程序中使用React useState时出现问题

按什么顺序接收`storage`事件?

将范围 Select 器添加到HighChart面积图

无法检索与Puppeteer的蒸汽游戏的Bundle 包价格

如果我的列有条件,我如何呈现图标?

调用特定数组索引时,为什么类型脚本不判断未定义

我如何才能获得价值观察家&对象&S的价值?

如何阻止外部脚本进入顶层导航

在点击链接后重定向至url之前暂停