选择子元素jQuery

Oni*_*lol 10 javascript jquery html5 liquid

我有一个像这样结构的表:

<table>
  <tbody>
  for loop here
    <tr>
      <td>Item X Attribute 1</td>
      <td>Item X Attribute 2</td>
      <td><button name="test" onclick="display_variants()">Hide my kids</button></td>
    </tr>
    <tr>
      <tbody class="variants_info">
        <tr>
          <td>Item X Variant 1</td>
          <td>Item X Variant 2</td>
        </tr>
      </tbody>
    </tr>
endfor loop
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

因此该结构重复Y次.

我正在尝试制作一个隐藏tbody.variants所选行的脚本.

到目前为止我所拥有的是:

<script>
  function display_variant(){
    if($('.variants_info').is(":visible")){
        $('.variants_info').hide();
    }
    else{
        $('.variants_info').show();
    }
  }
</script>
Run Code Online (Sandbox Code Playgroud)

但这隐藏了所有行的变体.

有没有办法选择特定行的孩子?另外我怎么能从tbody.variants隐藏开始?(从我访问页面时开始).

编辑:目前正在仔细研究: 在此输入图像描述

更新: 我已设法将结构更改为:

<table>
  for loop
    <tbody>
      <tr>
        <td>image for el 1</td>
        <td>attr for el 1</td>
        <td><button type='button' name='test'>Click Me</button></td>
      </tr>
      for loop
        <tr class='variants_info'>
          <td>variant1 for el 1</td>
          <td>variant2 for el 1</td>
        </tr>
      endfor
    </tbody>
  endfor
</table>
Run Code Online (Sandbox Code Playgroud)

更新2:实际代码是这样的:

<table class="pure-table pure-table-bordered">
  <tbody>
  {% for product in collection.products %}
  {% if product.available %}

    <tr class="{% cycle 'pure-table-odd', '' %}">
      <td>
        <img src="{{ product.featured_image.src | product_img_url: 'thumb' }}" alt="{{ product.featured_image.alt | escape }}" />
      </td>
      <td>{{ product.title }}</td>
      <td style="text-align:right">
        <button type="button" name="click_me">Click Me</button>
      </td>
      </tr>
      {% for variant in product.variants %}
    <tr>
      <td>{{variant.title}}</td>
      <td>{{variant.price | money }}</td>
    </tr>
    {% endfor %}       
        {% endif %}
        {% endfor %}
    </tbody>
</table>

<script>
  $("td button").click(function(){
    $(this).closest('tr').next().toggle();
  })
</script>
Run Code Online (Sandbox Code Playgroud)

我仍然无法让JS工作.. = /当前一个只隐藏第一个变体(而不是点击按钮的所有变体)

tri*_*cot 4

我建议用类名标记包含产品的行,例如“产品”,如下所示:

<tr class="product {% cycle 'pure-table-odd', '' %}">
  <td>
    <img src="{{ product.featured_image.src | product_img_url: 'thumb' }}" 
         alt="{{ product.featured_image.alt | escape }}" />
  </td>
  <td>{{ product.title }}</td>
  <td style="text-align:right">
    <button type="button" name="click_me">Click Me</button>
  </td>
</tr>
Run Code Online (Sandbox Code Playgroud)

您不会将该类添加到具有变体的行中。

然后在 JavaScript 中使用该nextUntil方法匹配所有下一个变体行(没有“产品”类),直到但不包括下一个产品行,并将该toggle()方法应用于所有这些:

$("td button").click(function(){
    $(this).closest('tr').nextUntil('.product').toggle();
});
Run Code Online (Sandbox Code Playgroud)

替代结构1

您可以创建包含变体的嵌套表,每个产品一个,而不是单个表。它看起来有点像这样:

<table class="pure-table pure-table-bordered">
  <tbody>
  {% for product in collection.products %}
  {% if product.available %}

    <tr class="{% cycle 'pure-table-odd', '' %}">
      <td>
        <img src="{{ product.featured_image.src | product_img_url: 'thumb' }}" 
             alt="{{ product.featured_image.alt | escape }}" />
      </td>
      <td>{{ product.title }}</td>
      <td style="text-align:right">
        <button type="button" name="click_me">Click Me</button>
      </td>
    </tr>
    <tr>
        <table class="some other class specific for variants">
          <tbody> 
            {% for variant in product.variants %}
            <tr>
              <td>{{variant.title}}</td>
              <td>{{variant.price | money }}</td>
            </tr>
            {% endfor %}
          </tbody>
        </table>
    </tr>
  {% endif %}
  {% endfor %}
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

这有优点也有缺点。主要缺点是这些子表的列与主表中的列不对齐。但这取决于你想要什么...

JavaScript 代码必须像最初一样:

$("td button").click(function(){
    $(this).closest('tr').next().toggle();
});
Run Code Online (Sandbox Code Playgroud)

替代结构2

您还可以用标签包装每个“部分”(由一个产品行和属于它的变体行组成)tbody。尽管不常见,但正如MDN上所述,这是允许的:

请注意,与<thead><tfoot><caption>元素不同,<tbody>允许多个元素(如果连续),从而允许将长表中的数据行分为不同的部分,每个部分根据需要单独格式化。

这与原始 HTML 不同,原始 HTML 中tbody元素是元素的子元素tr,这是无效的 HTML。

它看起来像这样:

<table class="pure-table pure-table-bordered">
  {% for product in collection.products %}
  {% if product.available %}

  <tbody>
    <tr class="{% cycle 'pure-table-odd', '' %}">
      <td>
        <img src="{{ product.featured_image.src | product_img_url: 'thumb' }}" 
             alt="{{ product.featured_image.alt | escape }}" />
      </td>
      <td>{{ product.title }}</td>
      <td style="text-align:right">
        <button type="button" name="click_me">Click Me</button>
      </td>
    </tr>
    {% for variant in product.variants %}
    <tr>
      <td>{{variant.title}}</td>
      <td>{{variant.price | money }}</td>
    </tr>
    {% endfor %}
  </tbody>
  {% endif %}
  {% endfor %}
</table>
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用该nextAll()方法隐藏变体行,因为它们由tbody包装器与下一个产品行分隔:

$("td button").click(function(){
    $(this).closest('tr').nextAll().toggle();
});
Run Code Online (Sandbox Code Playgroud)

最初隐藏变体行

如果您希望首先隐藏所有变体,请将以下属性添加到 HTML 代码中的这些行:

<tr style="display:hidden">
Run Code Online (Sandbox Code Playgroud)

您当然不会对产品行执行此操作。另外,您可能想为此定义一个 CSS 类(例如,tr.hidden { display:hidden; }而不是使用style.

jQuerytoggle()方法会在显示时覆盖它style,并在隐藏时再次恢复它。