【问题标题】:Expand only the selected row in a nested table仅展开嵌套表中的选定行
【发布时间】:2020-08-27 16:28:57
【问题描述】:

我正在尝试通过单击图标来展开表格中的嵌套行。最初,我是在点击下面的行时展开的。

$(function(){
    $(".fold-table tr.view").on("click", function(){
      $(this).toggleClass("open").next(".fold").toggleClass("open");
    });
  });

工作正常。现在,当我想在点击时展开时,我不知道用什么替换“this”关键字,所以它只会展开选定的行,而不是一次展开整个表格。

$(function(){
  $(".expand").on("click", function(){
    $(this).toggleClass("open").next(".fold").toggleClass("open");
  });
})
<body>

    <table class="table fold-table parent" id="table">
        <thead>
            <tr>

                <th scope="col">Name</th>
                <th scope="col">Designation</th>
                <th scope="col">Contact Details</th>
                <th scope="col">Email</th>
            </tr>
        </thead>
        <tbody>
            <tr class="view">

                <td col="Name">John</td>
                <td col="Designation">j@g.com</td>
                <td col="Contact Details">
                    <span class="contactInfo">
                        <img class="contact mr-2" src="./assets/call.png" />35373726<br>
                        <img class="contact mr-2" src="./assets/call.png" />35373726
                    </span>
                </td>
                <td col="Email">John@g.com<img class="expand ml-2" src="arrow.png" /></td>
            </tr>
            <tr class="fold">
                <td colspan="4">
                    <div class="fold-content">

                        <table class="child">

                            <tbody>
                                <tr>
                                    <td col="Name">SUB Category 1</td>
                                    <td col="Designation">SUB Category 2</td>
                                    <td col="Contact Details">SUB Category 3</td>
                                    <td col="Email">John@g.com
                                    
                                    </td>
                                </tr>

                                <tr>

                                    <td col="Name">SUB Category 1</td>
                                    <td col="Designation">SUB Category 2</td>
                                    <td col="Contact Details">SUB Category 3</td>
                                    <td col="Email">John@g.com
                                    
                                    </td>
                                </tr>
                                <tr>
                                    <td col="Name">SUB Category 1</td>
                                    <td col="Designation">SUB Category 2</td>
                                    <td col="Contact Details">SUB Category 3</td>
                                    <td col="Email">John@g.com
                                        
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </td>
            </tr>

        <tbody>
    </table>
</body>
.expand {
  cursor: pointer;
}

 table.fold-table > tbody > tr.fold {
  display: none;
}

table.fold-table > tbody > tr.fold.open {
  display: table-row;

}

为了演示,我只在父表中添加了一行,在子表中添加了三行。我怎样才能让这个扩展的东西工作?

您的帮助将不胜感激。

谢谢:)

【问题讨论】:

  • 您能否在示例中添加另一行或 2 行,以便我们了解其结构,以便我们知道如何选择正确的行?

标签: html jquery css


【解决方案1】:

您需要使用closest 函数获取tr,然后转到next() 类,即.foldtoggleClass('open')

工作演示:

$(function(){
  $(".expand").on("click", function(){
    $(this).toggleClass("open").closest('tr').next('.fold').toggleClass("open");
  });
})
.expand {
  cursor: pointer;
}

 table.fold-table > tbody > tr.fold {
  display: none;
}

table.fold-table > tbody > tr.fold.open {
  display: table-row;

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>

  <table class="table fold-table parent" id="table">
    <thead>
      <tr>

        <th scope="col">Name</th>
        <th scope="col">Designation</th>
        <th scope="col">Contact Details</th>
        <th scope="col">Email</th>
      </tr>
    </thead>
    <tbody>
      <tr class="view">

        <td col="Name">John</td>
        <td col="Designation">j@g.com</td>
        <td col="Contact Details">
          <span class="contactInfo">
            <img class="contact mr-2" src="./assets/call.png" />35373726<br>
            <img class="contact mr-2" src="./assets/call.png" />35373726
          </span>
        </td>
        <td col="Email">John@g.com<img class="expand ml-2" src="arrow.png" /></td>
      </tr>
      <tr class="fold">
        <td colspan="4">
          <div class="fold-content">
            <table class="child">

              <tbody>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">John@g.com

                  </td>
                </tr>

                <tr>

                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">John@g.com

                  </td>
                </tr>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">John@g.com
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </td>
      </tr>

    <tbody>
  </table>
</body>

【讨论】:

    【解决方案2】:

    在 vanilla Javascript 中,您可以使用以下答案:(对于 jQuery OP,请参阅@AlwaysHelping 帖子)

    我会保留原始代码,将前一个扩展添加为全局/类变量以在打开下一个之前将其关闭:

     document.querySelectorAll('tbody.toggle').forEach(e => (e.addEventListener('click', (e) => {
        const current = [e.currentTarget.querySelector('.view'), e.currentTarget.querySelector('.fold')];
        if (window.previous && window.previous[0] !== current[0]) {
          window.previous[0].classList.remove('open');
          window.previous[1].classList.remove('open');
        }
    
        current[0].classList.toggle('open');
        current[1].classList.toggle('open');
        window.previous = current;
      })));
    

    如果您决定使用 clases,请将 window 更改为正确的 this._property

    见下面的sn-p:

    <style>
      .fold {
        visibility: hidden;
      }
      .fold.open {
        visibility: visible;
      }
    </style>
    
    <body>
      <table class="table fold-table parent" id="table">
        <thead>
          <tr>
            <th scope="col">Name</th>
            <th scope="col">Designation</th>
            <th scope="col">Contact Details</th>
            <th scope="col">Email</th>
          </tr>
        </thead>
        <tbody class="toggle">
          <tr class="view">
            <td col="Name">John</td>
            <td col="Designation">j@g.com</td>
            <td col="Contact Details">
              <span class="contactInfo">
                <img class="contact mr-2" src="./assets/call.png" />35373726<br />
                <img class="contact mr-2" src="./assets/call.png" />35373726
              </span>
            </td>
            <td col="Email">John@g.com<img class="expand ml-2" src="arrow.png" /></td>
          </tr>
          <tr class="fold">
            <td colspan="4">
              <div class="fold-content">
                <table class="child">
                  <tbody>
                    <tr>
                      <td col="Name">SUB Category 1</td>
                      <td col="Designation">SUB Category 2</td>
                      <td col="Contact Details">SUB Category 3</td>
                      <td col="Email">John@g.com</td>
                    </tr>
                    <tr>
                      <td col="Name">SUB Category 1</td>
                      <td col="Designation">SUB Category 2</td>
                      <td col="Contact Details">SUB Category 3</td>
                      <td col="Email">John@g.com</td>
                    </tr>
                    <tr>
                      <td col="Name">SUB Category 1</td>
                      <td col="Designation">SUB Category 2</td>
                      <td col="Contact Details">SUB Category 3</td>
                      <td col="Email">John@g.com</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </td>
          </tr>
        </tbody>
        <tbody class="toggle">
          <tr class="view">
            <td col="Name">John 2</td>
            <td col="Designation">j@g.com</td>
            <td col="Contact Details">
              <span class="contactInfo">
                <img class="contact mr-2" src="./assets/call.png" />35373726<br />
                <img class="contact mr-2" src="./assets/call.png" />35373726
              </span>
            </td>
            <td col="Email">John@g.com<img class="expand ml-2" src="arrow.png" /></td>
          </tr>
          <tr class="fold">
            <td colspan="4">
              <div class="fold-content">
                <table class="child">
                  <tbody>
                    <tr>
                      <td col="Name">SUB Category 1</td>
                      <td col="Designation">SUB Category 2</td>
                      <td col="Contact Details">SUB Category 3</td>
                      <td col="Email">John@g.com</td>
                    </tr>
                    <tr>
                      <td col="Name">SUB Category 1</td>
                      <td col="Designation">SUB Category 2</td>
                      <td col="Contact Details">SUB Category 3</td>
                      <td col="Email">John@g.com</td>
                    </tr>
                    <tr>
                      <td col="Name">SUB Category 1</td>
                      <td col="Designation">SUB Category 2</td>
                      <td col="Contact Details">SUB Category 3</td>
                      <td col="Email">John@g.com</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </td>
          </tr>
        </tbody>
      </table>
    </body>
    
    <script>
      document.querySelectorAll('tbody.toggle').forEach(e => (e.addEventListener('click', (e) => {
        const current = [e.currentTarget.querySelector('.view'), e.currentTarget.querySelector('.fold')];
        if (window.previous && window.previous[0] !== current[0]) {
          window.previous[0].classList.remove('open');
          window.previous[1].classList.remove('open');
        }
    
        current[0].classList.toggle('open');
        current[1].classList.toggle('open');
        window.previous = current;
      })));
    </script>

    【讨论】:

    • 我没有完全理解。你能解释一下吗?上面建议的第一种方法不完整吗?
    • 我已经更新了帖子,希望它是不言自明的,如果不是让我知道的话
    • @aemonge 为什么你会建议其他 15 行代码来做同样的事情并让事情变得复杂以获得相同的结果。当一个简单整洁的函数closest 可以完成这项工作时。看我的回答。
    • @aemonge 在编写符合编码标准的代码时使用DRY 方法,即do not repeat yourself
    • @AlwaysHelping 我的目标是通过仅“打开”一行来提供帮助,这就是我认为的问题。正如你所说,使用.closest 可以更有效地完成它,尽管我曾经避免在 DOM 中进行横向导航。
    猜你喜欢
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多