javascript - 如何一次只显示一个div?

标签 javascript jquery

我有三个部分,其中有两个 div。在第一个按钮中,我有一个按钮,单击它后,我应该打开下一个按钮。然而,此时只有一个 div 是可见的(因此当您单击下一个 div 时,前一个 div 应该关闭)。我已经有了这个功能,但是再次单击按钮后 - 它不会关闭相应的 div。

我在 codepen 上设置了我的问题的示例:

https://codepen.io/hubertstrawa/pen/abOwWMJ
<section>
  <div class="product">
    <span class="btn">Show more</span>
    <p>Lorem ipsum</p>
  </div>
  <div class="product-more displayNone">
    Test
  </div>
</section>
$('.btn').click(function(e) {

  // only one div to be shown but can't be closed as well.
  $('.product-more').each(function(i, v) {
  $(this).removeClass('displayBlock');
  $(this).addClass('displayNone');
  })

  if ($(e.target).parent().next().hasClass('displayNone')) {
    $(e.target).parent().next().removeClass('displayNone');
    $(e.target).parent().next().addClass('displayBlock');
  } else {
    $(e.target).parent().next().removeClass('displayBlock');
    $(e.target).parent().next().addClass('displayNone');
  }

});

有什么想法可以让它发挥作用吗?

谢谢

最佳答案

更改父元素上的.is-open

<section class="product is-open">    <!-- is-open toggled by JS -->
    <div class="product-more"></div> <!-- handle children styles using CSS -->
</section>
                 .product-more { display: none; }  /* default */
.product.is-open .product-more { display: block; } /* when ancestor is .is-open*/

.on() 方法中使用 delegateTarget 来获取 .product 委托(delegate)者元素

const $product = $('.product'); // Collect all current products

$product.on('click', '.btn', function(e) {

  const $thisProd = $(e.delegateTarget);          // The .product delegator
  $product.not($thisProd).removeClass('is-open'); // Handle all (but not this)
  $thisProd.toggleClass('is-open');               // Handle current

});
/* QuickReset */ * {margin: 0; box-sizing: border-box;}

.product {
  background-color: #ededed;
  width: 400px;
  margin: 0 auto;
  margin-bottom: 1rem;
}

.product-title {
  position: relative;
  padding: 1rem;
}

.product .btn {
  position: absolute;
  bottom: 0;
  right: 0;
  padding: .7rem;
  background-color: cyan;
  cursor: pointer;
}

.product-more {
  width: 100%;
  padding: 1rem;
  background-color: cyan;
  display: none; /* by default */
}

.product.is-open .product-more {
  display: block;
}
<section class="product">
  <div class="product-title">
    <p>Lorem ipsum</p>
    <span class="btn">Show more</span>
  </div>
  <div class="product-more">Test</div>
</section>

<section class="product">
  <div class="product-title">
    <p>Lorem ipsum</p>
    <span class="btn">Show more</span>
  </div>
  <div class="product-more">Test</div>
</section>

<section class="product">
  <div class="product-title">
    <p>Lorem ipsum</p>
    <span class="btn">Show more</span>
  </div>
  <div class="product-more">Test</div>
</section>

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

这是首选,因为它可以让您更改 HTML 和 CSS,而不必再担心 JavaScript - 同时使用 .prev().next().parent() (就像其他答案所建议的那样)JS 只是在等待您更改标记 - 来打破。

  • 无需来回遍历选择器。
  • product-more 元素上不需要 .displayNone.displayBlock
<小时/>

处理动态.product

如果您的 .product 是动态元素,这里是上述概念的另一个解决方案:

$('.allProducts').on('click', '.btn', function(e) {

  const $product = $(e.delegateTarget).find('.product'); // Get all .product
  const $thisProd = $(this).closest('.product'); // The closest .product ancestor
  $product.not($thisProd).removeClass('is-open'); // Handle all (but not this)
  $thisProd.toggleClass('is-open'); // Handle current

});
/* QuickReset */ * {margin: 0; box-sizing: border-box;}

.product {
  background-color: #ededed;
  width: 400px;
  margin: 0 auto;
  margin-bottom: 1rem;
}

.product-title {
  position: relative;
  padding: 1rem;
}

.product .btn {
  position: absolute;
  bottom: 0;
  right: 0;
  padding: .7rem;
  background-color: cyan;
  cursor: pointer;
}

.product-more {
  width: 100%;
  padding: 1rem;
  background-color: cyan;
  display: none; /* by default */
}

.product.is-open .product-more {
  display: block;
}
<div class="allProducts">

  <section class="product">
    <div class="product-title">
      <p>Lorem ipsum</p>
      <span class="btn">Show more</span>
    </div>
    <div class="product-more">Test</div>
  </section>

  <section class="product">
    <div class="product-title">
      <p>Lorem ipsum</p>
      <span class="btn">Show more</span>
    </div>
    <div class="product-more">Test</div>
  </section>

  <section class="product">
    <div class="product-title">
      <p>Lorem ipsum</p>
      <span class="btn">Show more</span>
    </div>
    <div class="product-more">Test</div>
  </section>

</div>

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

关于javascript - 如何一次只显示一个div?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60474684/

相关文章:

javascript - 在 HTML 中使用 document.getElementById 清除段落

javascript - 获取 JSON 键的文本值

javascript - 从 Rally getSettingsFields 获取数据 - checkboxfield

javascript - 如何通过不同的脚本异步传递变量

javascript - 如何更改 vimeo 默认皮肤

javascript - 如何在 svg-objects 中存储自定义数据?

javascript - 如何使用 Bootstrap 使我的网站具有响应性?

jquery - 如何设置 slider 样式

jquery - 全宽 - 正常高度 BG Img

javascript - 使用Jquery检索YouTube标签