onClick javascript 函数仅显示包装器的第一个子项

onClick javascript function shows only first child of wrapper

最近在学习javascript,代码有点问题

我在页面 wrapper1wrapper2wrapper3 上有三个元素,每个元素都有其 triggerredbox 元素。

我的目标是当 trigger 被击中时,它会显示对应于数字的 redbox 元素。

例子: 单击 wrapper1 元素内的 trigger1 会显示 redbox1 元素, trigger2 里面的 wrapper2 元素显示 redbox2 元素等

问题是,当我点击 trigger3 时,它总是显示 redbox1 元素。 (如示例所示)。

我做错了什么?我只是个初学者

function showTheRedBox() {
  var theRedBox = document.getElementsByClassName('redbox');
  theRedBox[0].style.display = 'block';
}
body {background: #222;}
.wrapper {
  background: yellow;
  width: 100px;
  height: 100px;
}
.trigger {
  background: blue;
  width: 50px;
  height: 50px;
  position: absolute;
  margin-top: 50px;
  margin-left: 50px;
}
.redbox {
  background: red;
  width: 200px;
  height: 100px;
  margin-left: 100px;
  position: absolute;
  display: none;
}
<div class="wrapper">
  <div class="trigger" onclick="showTheRedBox();">trigger1</div>
  <div class="redbox">hurrah1</div>
wrapper1</div>
<div class="wrapper">
  <div class="trigger" onclick="showTheRedBox();">trigger2</div>
  <div class="redbox">hurrah2</div>
wrapper2</div>
<div class="wrapper">
  <div class="trigger" onclick="showTheRedBox();">trigger3</div>
  <div class="redbox">hurrah3</div>
wrapper3</div>

您可以使用 for 循环和闭包来访问每个 onclick 事件的 .wrapper 信息。无论 children 数量是否相同,此方法都有效,并且始终显示正确的 child.

此外,最好不要使用内联 JavaScript 属性(例如 onclick="showTheRedBox();"),为了可读性和可维护性,您应该始终在脚本中分配事件处理程序。

var wrappers = document.querySelectorAll('.wrapper'), i;
var redboxes = document.querySelectorAll('.redbox');

for(i = wrappers.length - 1; i >= 0; --i) {
  (function(wrapper){
    wrapper.querySelector('.trigger').onclick = function() {
      hideAll();
      wrapper.querySelector('.redbox').style.display = 'block';
    }
  })(wrappers[i]);
}

function hideAll() {
  for(i = redboxes.length - 1; i >= 0; --i) {
    redboxes[i].style.display = 'none';
  }
}

var wrappers = document.querySelectorAll('.wrapper'), i;
var redboxes = document.querySelectorAll('.redbox');

for(i = wrappers.length - 1; i >= 0; --i) {
  (function(wrapper){
    wrapper.querySelector('.trigger').onclick = function() {
      hideAll();
      wrapper.querySelector('.redbox').style.display = 'block';
    }
  })(wrappers[i]);
}

function hideAll() {
  for(i = redboxes.length - 1; i >= 0; --i) {
    redboxes[i].style.display = 'none';
  }
}
body {background: #222;}
.wrapper {
  background: yellow;
  width: 100px;
  height: 100px;
}
.trigger {
  background: blue;
  width: 50px;
  height: 50px;
  position: absolute;
  margin-top: 50px;
  margin-left: 50px;
}
.redbox {
  background: red;
  width: 200px;
  height: 100px;
  margin-left: 100px;
  position: absolute;
  display: none;
}
<div class="wrapper">
  <div class="trigger">trigger1</div>
  <div class="redbox">hurrah1</div>
wrapper1</div>
<div class="wrapper">
  <div class="trigger">trigger2</div>
  <div class="redbox">hurrah2</div>
wrapper2</div>
<div class="wrapper">
  <div class="trigger">trigger3</div>
  <div class="redbox">hurrah3</div>
wrapper3</div>


此方法也有效,但它会比上述解决方案多查询一次 DOM,因此会使用更多内存。

var wrappers = document.querySelectorAll('.wrapper'), i;
var redboxes = document.querySelectorAll('.redbox');

for(i = wrappers.length - 1; i >= 0; --i) {
  wrappers[i].querySelector('.trigger').onclick = function() {
    hideAll();
    this.parentNode.querySelector('.redbox').style.display = 'block';
  }
}

function hideAll() {
  for(i = redboxes.length - 1; i >= 0; --i) {
    redboxes[i].style.display = 'none';
  }
}

var wrappers = document.querySelectorAll('.wrapper'), i;
var redboxes = document.querySelectorAll('.redbox');

for(i = wrappers.length - 1; i >= 0; --i) {
  wrappers[i].querySelector('.trigger').onclick = function() {
    hideAll();
    this.parentNode.querySelector('.redbox').style.display = 'block';
  }
}

function hideAll() {
  for(i = redboxes.length - 1; i >= 0; --i) {
    redboxes[i].style.display = 'none';
  }
}
body {background: #222;}
.wrapper {
  background: yellow;
  width: 100px;
  height: 100px;
}
.trigger {
  background: blue;
  width: 50px;
  height: 50px;
  position: absolute;
  margin-top: 50px;
  margin-left: 50px;
}
.redbox {
  background: red;
  width: 200px;
  height: 100px;
  margin-left: 100px;
  position: absolute;
  display: none;
}
<div class="wrapper">
  <div class="trigger">trigger1</div>
  <div class="redbox">hurrah1</div>
wrapper1</div>
<div class="wrapper">
  <div class="trigger">trigger2</div>
  <div class="redbox">hurrah2</div>
wrapper2</div>
<div class="wrapper">
  <div class="trigger">trigger3</div>
  <div class="redbox">hurrah3</div>
wrapper3</div>

您遇到的问题是方法 "getElementsByClassName",returns 您是一个数组,其中包含 class 的所有元素。所以,当你这样做的时候:

theRedBox[0].style.display = 'block'

您正在更改数组的 First 元素的显示样式,在本例中为 "wrapper1".

这是一个可以与其他包装器一起运行的修改版本:

<!DOCTYPE html>
<html lang = 'es'>
    <head>
        <title> MY TEST </title>
        <style>
            body {
                background: #222;
            }
            .wrapper {
              background: yellow;
              width: 100px;
              height: 100px;
            }
            .trigger {
              background: blue;
              width: 50px;
              height: 50px;
              position: absolute;
              margin-top: 50px;
              margin-left: 50px;
            }
            .redbox {
              background: red;
              width: 200px;
              height: 100px;
              margin-left: 100px;
              position: absolute;
              display: none;
            }
        </style>
    </head>
    <body>
        <div class="wrapper">
          <div class="trigger" onclick="showTheRedBox(0)">trigger1</div> <!-- When the onClick event is trigered the function "showTheRedBox receives a parameter , that parameter is the position of the element in the Array "theRedBox"-->
          <div class="redbox">hurrah1</div>
        wrapper1
        </div>

        <div class="wrapper">
            <div class="trigger" onclick="showTheRedBox(1)">trigger2</div>
            <div class="redbox">hurrah2</div>
        wrapper2
        </div>

        <div class="wrapper">
              <div class="trigger" onclick="showTheRedBox(2)">trigger3</div>
              <div class="redbox">hurrah3</div>
        wrapper3</div>

        <script>

            function showTheRedBox(wrapperNumber) {
                  var theRedBox = document.getElementsByClassName('redbox');
                  theRedBox[wrapperNumber].style.display = 'block';
                }
        </script>
    </body>
</html>