首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我希望在不使用class或ID的情况下,在下一个父级兄弟中定位子元素

我希望在不使用class或ID的情况下,在下一个父级兄弟中定位子元素
EN

Stack Overflow用户
提问于 2018-12-19 01:24:42
回答 2查看 59关注 0票数 0

下面是html (它出现在多个地方,但每个外观都应该有不同的处理方式):

代码语言:javascript
复制
<div class="foot-nav-heading">Click me!</div>
    <div class="textwidget">
       <ul class="quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

以下是javascript代码:

代码语言:javascript
复制
var accordions = document.getElementsByClassName("foot-nav-heading");
  for (var i = 0; i < accordions.length; i++) {
     accordions[i].onclick = function() {
       this.classList.toggle('is-open');

   var content = this.nextElementSibling;
   if (content.style.maxHeight) {
   // accordion is currently open, so close it
 content.style.maxHeight = null;
   } else {
  // accordion is currently closed, so open it
 content.style.maxHeight = content.scrollHeight + "px";
   }
 }
}

我想把"div.textwidget“元素中的"ul”作为目标。我试过了

代码语言:javascript
复制
var content = this.next.(".text-widget").find(".accordion-content")

但它不起作用。

提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2018-12-19 01:45:06

你的代码可以工作了!问题不在于同级,问题在于不能将css高度设置为null

代码语言:javascript
复制
var accordions = document.getElementsByClassName("foot-nav-heading");
  for (var i = 0; i < accordions.length; i++) {
     accordions[i].onclick = function() {
       this.classList.toggle('is-open');
   var content = this.nextElementSibling;

   if (content.style.maxHeight != "0px") {
   // accordion is currently open, so close it
 content.style.maxHeight = "0px";
   } else {
  // accordion is currently closed, so open it
 content.style.maxHeight = "200px";
   }
 }
}
代码语言:javascript
复制
<div class="foot-nav-heading">Click me!</div>
    <div class="textwidget">
       <ul class="quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

Here is the javascript code:

<div class="foot-nav-heading">Click me!</div>
    <div class="textwidget">
       <ul class="quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

Here is the javascript code:

编辑

您在代码中尝试的是获取nextSibling。但是您可能有额外的带有回车符的文本节点,请尝试以下代码片段:

代码语言:javascript
复制
document.querySelectorAll(".textwidget")[0].childNodes.forEach(function(el){
  console.log(el.nodeName,el.nodeType);
});
代码语言:javascript
复制
<div class="foot-nav-heading">Click me!</div>
    <div class="textwidget">
    <ul class="quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

所以尝试直接定位是有风险的(在你的例子中,你可以用content.childNodes[1]得到你想要的东西,但是如果你不知道html是怎么写的,那就很危险了。它可以是不带回车符的content.childNodes[0] )。因此,最好的选择是解析childNodes并设置一个变量,或者在数组中的push元素满足条件时将其推入数组。在您的案例中:

代码语言:javascript
复制
var ul;
content.forEach(function(el){
  if (el.nodeName === 'UL') ul = el;
}

或者从节点列表中创建一个数组来过滤所需的节点:

代码语言:javascript
复制
var ul = Array.from(document.querySelectorAll(".textwidget")[0].childNodes).filter(function(el) {if(el.nodeName == 'UL') return el});

// or use es6 features
// var ul = [...document.querySelectorAll(".textwidget")[0].childNodes].filter(e => e.nodeName == 'UL');

console.log(ul[0]);
代码语言:javascript
复制
<div class="foot-nav-heading">Click me!</div>
    <div class="textwidget">
       <ul class="quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

票数 1
EN

Stack Overflow用户

发布于 2018-12-19 04:04:30

Event Delegation

单击此父标记上的(main#main)

  • Register事件时,将标记中的所有折叠框换行。

  • 现在,任何单击父标记的操作都会被其中嵌套的标记检测到。

  • 通过使用e.target,您可以准确地确定是哪个标记clicked.

支持无限数量的标记

XY Problem

关于OP的目标:

“我希望在不使用类或ID的情况下指向下一个同级父元素中的子元素。”

考虑到实际的布局,每个“按钮”都可以针对nextElementSibling添加/删除一个类,并且仍然能够通过使用CSS选择器来影响nextElementSibling的子级。简而言之,将嵌套在父级中的标记定位为更容易访问的标记是浪费精力和时间的,反过来也更容易通过CSS访问它的子代。

布局

代码语言:javascript
复制
<button>CLICK</button>

<section class='accordion'>
  <ul class='list'>
    <li>ITEM</li>
  </ul>
</section>

CSS

代码语言:javascript
复制
/* By default this hides .list */
.accordion {
  max-height: 0;
  opacity: 0;
  font-size: 0;
  transition: all 0.3s;
  border: 3px outset #666;
}

/* This class is added/removed when <button> is clicked */
/* .open is nextElementSibling and anytime .open is added, it's child .list 
   benefits from it as well
 */
.open,
.open .list {
  height: auto;
  max-height: 1000px;
  opacity: 1;
  font-size: 16px;
  transition: all 0.3s;
  border: 3px outset #666;
}

演示

在演示中评论的详细信息

代码语言:javascript
复制
// Reference the parent tag (main#main)
var main = document.getElementById('main');

/*
Register <main> to the click event...
toggleText() is the callback function
*/
main.addEventListener('click', toggleText);

// Pass the Event Object (e)
function toggleText(e) {
  // Reference e.target -- clicked tag (header.head) 
  var tgt = e.target;
  /*
  Reference the next adjacent sibling of e.target (article.text)
  */
  var actTxt = tgt.nextElementSibling;
  // Collect all article.text into a NodeList
  var txts = document.querySelectorAll('.text');
  // if clicked tag has class .head...
  if (tgt.classList.contains('head')) {
    /*
    On each loop...
    if the current article.text is NOT e.target's .text sibling...
    ...remove class .open.
    Toggle .open class on e.target's .text sibling.
    */
    for (let i = 0; i < txts.length; i++) {
      if (txts[i] !== actTxt) {
        txts[i].classList.remove('open');
      }
    }
    actTxt.classList.toggle('open');
  }
}
代码语言:javascript
复制
.head {
  cursor: pointer;
  border: 3px outset #666;
  text-align:center;
  padding: 3px 5px;
}

.text {
  max-height: 0;
  opacity: 0;
  font-size: 0;
  transition: all 0.3s;
  border: 3px outset #666;
}

.open,
.open .menu {
  height: auto;
  max-height: 1000px;
  opacity: 1;
  font-size: 16px;
  transition: all 0.3s;
  border: 3px outset #666;
}
代码语言:javascript
复制
<main id='main'>

  <header class="head">MENU</header>
  <article class="text">
    <ul class="menu">
      <li>ITEM 1</li>
      <li>ITEM 2</li>
      <li>ITEM 3</li>
    </ul>
  </article>

  <header class="head">MENU</header>
  <article class="text">
    <ul class="menu">
      <li>ITEM 1</li>
      <li>ITEM 2</li>
      <li>ITEM 3</li>
    </ul>
  </article>

  <header class="head">MENU</header>
  <article class="text">
    <ul class="menu">
      <li>ITEM 1</li>
      <li>ITEM 2</li>
      <li>ITEM 3</li>
    </ul>
  </article>

</main>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53838171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档