繁体   English   中英

如何一次只显示一个div?

[英]How to show only one div at the time?

我有三个部分,其中有两个 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*/

内部使用delegateTarget .on()方法来取回.product委托元素

 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>

单击任何btn按钮时,您正在隐藏所有product-more部分,然后尝试显示/隐藏与单击的按钮关联的product-more部分。

因此,当product-more部分已经显示并且您单击它的btn按钮时,发生的情况是您首先隐藏关联的部分,然后您的代码检查它是否不可见,然后再次显示它。

一种可能的解决方案是在隐藏时丢弃相关的product-more部分。 此外,由于默认显示div ,因此您不需要displayBlock类。

$('.btn').click(function(e) {
    var $current = $(e.target).parent().next('.product-more');

    // Hide all sections that are not the one associated to the current button.
    $('.product-more').not($current).addClass('displayNone');

    // Show or hide current section.
    $current.toggleClass('displayNone');
});

您可以使用toggleClass它将检测您的类并将其更改为另一个类。

在您的 each 函数中,您只需要将所有项目设置为隐藏,然后它将切换当前项目的类。

代码笔

https://codepen.io/nasser-ali-karimi/pen/rNVwwLy?editors=1010

$('.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');
  })
 $(e.target).parent().next().toggleClass('displayNone displayBlock');

});

使用 jQuery 的较短版本将使用hide()toggle():

 $('.btn').click(function(e) { var more = $(e.target).parent().next() ; $('.product-more').not(more).hide(); $(e.target).parent().next().toggle(); });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM