JavaScript事件处理程序:切换相邻元素的可见性。代码无效

时间:2018-02-08 18:51:53

标签: javascript css event-handling

我嵌套了无序列表。每个无序列表都有一个h1标记作为其“previous-sibling”标记。我的目标是点击一个h1标签并切换紧随其后的无序列表的可见性。

我还试图根据标题(h1)标签为每个无序列表分配classNames。

是否有人能够帮助我理解为什么我的代码无效?

以下是代码:

window.onload = function() {
  
  let titles = document.getElementsByTagName('h1');
  for (let i = 0 ; i < titles.length ; i++) {
    let title = titles[i];
    //grab the text in the h1 element, and add that text as a class to the h1:
    let className = title.innerHTML.toLowerCase();
    title.className += title.className.length ?  ' ' + className : className;
    let section = document.querySelectorAll(`.${className} + ul`);
    if(section.length) {
      section[0].className += section[0].className.length 
      ?  
      ` ${className} section` 
      : 
      `${className} section`;
      //ADD EVENT HANDLER TO THE TITLE.
      //SHOULD HIDE AND SHOW THE ADJASCENT UL ELEMENT:
      title.onclick = function(e) {
        section[0].classList.toggle('hide'); 
      };
    }
  } 
};
/* trying to toggle visibility with this class*/

.hide {
  display: none;
}

/*basic styles to separate elements:*/

h1 {
  color: olive;
}

ul {
  border: solid orange 1px;
}


li {
  //border: solid magenta 1px;
}
<div id="foods">
  <h1>Food</h1>
  <ul>
    <li>
      <h1>Fruit</h1>
      <ul>
        <li>
          <h1>tropical</h1>
          <ul>
            <li>banana</li>
            <li>pineapple</li>
            <li>mango</li>
          </ul>
        </li>
        <li>
          <h1>stone</h1>
          <ul>
            <li>peach</li>
            <li>pear</li>
            <li>appricot</li>
          </ul>
        </li>
      </ul>
    </li>
    <li>
      <h1>Vegetables</h1>
      <ul>
        <li>
          <h1>leafy</h1>
          <ul>
            <li>lettuce</li>
            <li>spinach</li>
            <li>kale</li>
           </ul>
        </li>
        <li>
          <h1>root</h1>
          <ul>
            <li>carrot</li>
            <li>turnip</li>
            <li>potato</li>
           </ul>
        </li>
      </ul>
    </li>
  </ul> 
</div>

1 个答案:

答案 0 :(得分:3)

主要问题是你使用了错误的CSS属性。您想要display,而不是visibility

.hide {
  display: none;
}

如果您使用的是visibility,则值为hidden,但会继续占用布局空间,我确信这不是您想要的。

但是另外,连接这些事件处理程序并添加这些类的代码(你以后说过你将它们用于以后的事情)可能会更简单一些:

window.onload = function() {
  function toggleNext() {
    this.nextElementSibling.classList.toggle("hide");
  }
  let titles = document.getElementsByTagName('h1');
  for (let i = 0 ; i < titles.length ; i++) {
    const title = titles[i];
    const section = title.nextElementSibling;
    const titleClass = title.innerHTML.toLowerCase();
    title.classList.add(titleClass);
    section.classList.add(titleClass, "section");
    titles[i].addEventListener("click", toggleNext);
  } 
};

直播示例:

window.onload = function() {
  function toggleNext() {
    this.nextElementSibling.classList.toggle("hide");
  }
  let titles = document.getElementsByTagName('h1');
  for (let i = 0 ; i < titles.length ; i++) {
    const title = titles[i];
    const section = title.nextElementSibling;
    const titleClass = title.innerHTML.toLowerCase();
    title.classList.add(titleClass);
    section.classList.add(titleClass, "section");
    titles[i].addEventListener("click", toggleNext);
  } 
};
/* trying to toggle visibility with this class*/

.hide {
  display: none;
}

/*basic styles to separate elements:*/

h1 {
  color: olive;
}

ul {
  border: solid orange 1px;
}


li {
  //border: solid magenta 1px;
}
<div id="foods">
  <h1>Food</h1>
  <ul>
    <li>
      <h1>Fruit</h1>
      <ul>
        <li>
          <h1>tropical</h1>
          <ul>
            <li>banana</li>
            <li>pineapple</li>
            <li>mango</li>
          </ul>
        </li>
        <li>
          <h1>stone</h1>
          <ul>
            <li>peach</li>
            <li>pear</li>
            <li>appricot</li>
          </ul>
        </li>
      </ul>
    </li>
    <li>
      <h1>Vegetables</h1>
      <ul>
        <li>
          <h1>leafy</h1>
          <ul>
            <li>lettuce</li>
            <li>spinach</li>
            <li>kale</li>
           </ul>
        </li>
        <li>
          <h1>root</h1>
          <ul>
            <li>carrot</li>
            <li>turnip</li>
            <li>potato</li>
           </ul>
        </li>
      </ul>
    </li>
  </ul> 
</div>

附注:我建议不要使用window.load,除非您真的需要此代码等待所有图像,样式表等在运行之前完全加载。相反,只需确保代码位于文档末尾的script标记中,就在结束</body>代码之前。