如何在 Class 语法中仅展开其 parents 中的一个 child 元素?

How to unfold only a child element of its parents own in Class Syntax?

我正在尝试 select 其 parent 自己的 child 元素 (a.k.a firstPanel) 在 Class 语法中但是不知道我该怎么做。

在普通函数中引用 each firstPanel 很容易,而且像这样工作得很好:

$(function accordian() {
  $('.mobileCategory').on('click', function() {
    if (!$(this).hasClass('open')) {
      $(this).addClass('open');
      $(this).siblings('.firstPanel').stop(true, true).animate({
        maxHeight: 1000 + 'px'
      });
    } else if ($(this).hasClass('open')) {
      $(this).removeClass('open');
      $(this).siblings('.firstPanel').stop(true, true).animate({
        maxHeight: null
      });
    }
  })
})

但是当我点击 Class 语法下的元素时,整个 .firstPanel 将展开如下:

我知道 this.list 假设整个 firstPanel。我只是不知道如何在 Class 语法中引用 parent 的 child 元素。

有没有办法做到这一点?

完整代码:

class Accordian {
  constructor($el) {
    this.$el = $el;
    this.category = this.$el.find('.mobileCategory');
    this.list = this.category.siblings();
    /* Boolean Flags */
    this.flags = {
      active: false,
    };
  }
  clicked(e) {
    console.log('text')
    this.list.css({
      maxHeight: 1000 + 'px'
    })
  }
  manange() {
    console.log(this.list, 'text');
    this.$el.on({['click']: (e) => this.clicked(e)});
  }
}
var thatAccordian = new Accordian($('#mobile-menu'));
    thatAccordian.manange();
a {
  text-decoration: none;
  color: white;
}
#mobile-menu {
  position: absolute;
  z-index: 999;
  color: white;
  width: 100%;
  height: calc(100% - 110px);
  top: 110px;
  background-color: #202020;
}
.wrapper, li {
  display: block;
  flex-flow: column;
  margin: 1rem;
  transition: all 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.wrapper > li > ul {
  transition: all 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  display: block;
  flex-flow: column;
  max-height: 0;
  overflow: hidden;
  margin: 0 1rem;
}
.wrapper > li > ul > li {
  transition: all 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  display: block;
  flex-flow: column;
  margin: 1rem 0;
  font-size: .8rem;
  outline-width: 0;
  border-width: 0;
  border-bottom: 1px solid white;
}
  <div id="mobile-menu">
    <ul class="wrapper">
      <li>
        <a href="#" class="mobileCategory">MODELS</a>
        <ul class="firstPanel">
          <li>URUS</li>
          <li>HURACÁN</li>
          <li>AVENTADOR</li>
          <li>FEW OFF</li>
          <li>CONCEPT</li>
          <li>AD PERSONAM</li>
          <li>OVERVIEW</li>
        </ul>
      </li>
      <li>
        <a href="#" class="mobileCategory">BRAND</a>
        <ul class="firstPanel">
          <li>PEOPLE</li>
          <li>HISTORY</li>
          <li>MASTERPIECE</li>
          <li>DESIGN</li>
          <li>INNOVATION & EXCELLENCE</li>
          <li>OVERVIEW</li>
        </ul>
      </li>
      <li>
      <li><a href="#" class="mobileCategory">MOTORSPORT</a></li>
      <li><a href="#" class="mobileCategory">STORE</a></li>
    </ul>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

好吧,根据您的评论,我认为您可能想重新审视您的 Accordian 设计。这里有一些提示:

  • 你说 每个 mobileCategories 都是 Accordian 但是,当你像这样创建一个 Accordian 对象时:var thatAccordian = new Accordian($('#mobile-menu'));,你说的是一对一- thatAccordian#mobile-menu 之间的一种关系,你说呢?
  • 现在看看构造函数,当你说 this.$el = $el; 时,this.$el#mobile-menu 结束,而不是一个 .mobileCatetgory;同样,当您写 this.category = this.$el.find('.mobileCategory'); 时,有人可能会认为 category(单数)category 以一个 .mobileCategory 元素结尾,但事实并非如此。尝试 console.log-ing 它,您将看到 category 如何包含所有(此代码段中的 4 个)类别元素 s。最后,this.list = this.category.siblings(); 也会发生同样的情况; this.list 将包含 #mobile-menu 内的所有(此代码段中的 2 个)uls,它们是 .mobileCategory 的兄弟姐妹(这就是为什么现在正在扩展两个元素而不是仅仅单击的那个)。

所以,我的建议是,再次检查您的 Accordian,但目前,这里有一个片段可以满足您的实际需求。

就像现在一样,在您的 clicked(e) 函数中,您需要使用事件参数 (e) 以获得被单击的确切元素,然后应用所需的任何样式对于它或它的兄弟姐妹的动画。此外,我建议尽可能 adding/removing/toggling CSS 类 并在 CSS 文件中创建那些 类,而不是从 JS 编辑 CSS 代码。

最后一件事,我删除了代码段中的这一行 height: calc(100% - 110px);,否则当列表展开时黑色背景会丢失。此外,运行 全屏模式下的代码段。

class Accordian {
  constructor($el) {
    this.$el = $el;
    this.category = this.$el.find('.mobileCategory');
    this.list = this.category.siblings();
    
    /* Boolean Flags */
    this.flags = {
      active: false,
    };
  }
  clicked(e) {
    //console.log($(e.target))
    
    $(e.target).siblings('ul').toggleClass('expanded');
    /*this.list.css({
      maxHeight: 1000 + 'px'
    })*/
  }
  manange() {
    //console.log(this.list, 'text');
    this.$el.on({['click']: (e) => this.clicked(e)});
  }
}
var thatAccordian = new Accordian($('#mobile-menu'));
    thatAccordian.manange();
a {
  text-decoration: none;
  color: white;
}
#mobile-menu {
  position: absolute;
  z-index: 999;
  color: white;
  width: 100%;
  /*height: calc(100% - 110px);*/
  top: 110px;
  background-color: #202020;
}
.wrapper, li {
  display: block;
  flex-flow: column;
  margin: 1rem;
  transition: all 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.wrapper > li > ul {
  transition: all 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  display: block;
  flex-flow: column;
  max-height: 0;
  overflow: hidden;
  margin: 0 1rem;
}
.wrapper > li > ul > li {
  transition: all 500ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  display: block;
  flex-flow: column;
  margin: 1rem 0;
  font-size: .8rem;
  outline-width: 0;
  border-width: 0;
  border-bottom: 1px solid white;
}

.wrapper > li > ul.expanded{
  max-height: 1000px;
}
<div id="mobile-menu">
    <ul class="wrapper">
      <li>
        <a href="#" class="mobileCategory">MODELS</a>
        <ul class="firstPanel">
          <li>URUS</li>
          <li>HURACÁN</li>
          <li>AVENTADOR</li>
          <li>FEW OFF</li>
          <li>CONCEPT</li>
          <li>AD PERSONAM</li>
          <li>OVERVIEW</li>
        </ul>
      </li>
      <li>
        <a href="#" class="mobileCategory">BRAND</a>
        <ul class="firstPanel">
          <li>PEOPLE</li>
          <li>HISTORY</li>
          <li>MASTERPIECE</li>
          <li>DESIGN</li>
          <li>INNOVATION & EXCELLENCE</li>
          <li>OVERVIEW</li>
        </ul>
      </li>
      <li>
      <li><a href="#" class="mobileCategory">MOTORSPORT</a></li>
      <li><a href="#" class="mobileCategory">STORE</a></li>
    </ul>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>