简体   繁体   中英

Using jQuery .slideToggle() with display: grid;

I have a set of collapsible/expandable elements, and I would like to have the inner content laid out in a display:grid format.

In my current setup, I use a hook in the $().slideToggle() method to call an anonymous function that checks if the element is visible and forces the display to grid.

This isn't a good solution as it stands, because the content is not in grid format during the expansion animation the first time the content is shown. It only applies the correct format after the animation is complete. See jsfiddle here .

What is the appropriate way to set this up in css/jquery so that the inner expandable content shows as grid even during the first animation?

HTML

<div class="user-products main">
        <div class="user-product">
            <div class ="collapsible-header">
                <span class="user-product-expand-toggle"><h4>&#9654; Product 1 - 2020-02-03 1:58pm</h4></span>
            </div>
            <div class="user-product-details hide">
                <div class="user-product-left">
                <p>Download All Files as Zip</p>
                <p>View Preview</p>
                <p>Details</p>
                <p>Details</p>
                <p>Details</p>
                </div>
                <div class="user-product-mid">
                <p>Details</p>
                <p>Details</p>
                <p>Details</p>
                <p>Details</p>
                <p>Details</p>
                </div>
                <div class="user-product-right">
                <div class="unpurchased-product"><button class="purchase-product">Purchase</button></div>
                </div>
            </div>
        </div>
        <div class="user-product">
            <div class ="collapsible-header">
                <span class="user-product-expand-toggle"><h4>&#9654; Product 2 - 2020-02-07 5:01pm</h4></span>
            </div>
            <div class="user-product-details hide">
                <div class="user-product-left">
                <p>Download All Files as Zip</p>
                <p>View Preview</p>
                <p>Details</p>
                <p>Details</p>
                <p>Details</p>
                </div>
                <div class="user-product-mid">
                <p>Details</p>
                <p>Details</p>
                <p>Details</p>
                <p>Details</p>
                <p>Details</p>
                </div>
                <div class="user-product-right">
                <div class="unpurchased-product"><button class="purchase-product">Purchase</button></div>
                </div>
            </div>
        </div>
    </div>

jQuery

$(".user-product-expand-toggle").click(function(){
    parentDiv = $(this).closest(".collapsible-header");
    $(parentDiv.siblings(".user-product-details")[0]).slideToggle('slow', function() {
        if ($(this).is(':visible'))
            $(this).css('display','grid');
    });

});

CSS

.hide.hide {
  display: none;
}

.user-products.main {
    overflow-y:auto;
}
.user-product-details {
    margin-left:50px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
}

.collapsible-header{
    margin-left:50px;
    text-align: left;
    cursor: pointer;

}

Instead of using slideToggle, use slideUp and slideDown.

Example:

$(".user-product-expand-toggle").click(function(){

    parentDiv = $(this).closest(".collapsible-header");

    let $element = $(parentDiv.siblings(".user-product-details")[0]);

    if ($element.is(':visible')) {
        $element.slideUp();
    }
    else {
        $element.slideDown({
            start: function() {
              $(this).css('display','grid');
            }
        });
    }

});

Demo Fiddle

jQuery use display property with slideToggle method. This jQuery design is incompatible with the alignment of the display property.

Therefore, this problems easily workaround is following:

  1. Use height property slide animation and switched display property when animation start and end.
  2. Divide into two parts, one to hide the elements and one to align the elements.

Simply solition is wrap grid container by hidden container (2. solution):

 $(".user-product-expand-toggle").click(function() { parentDiv = $(this).closest(".collapsible-header"); $(parentDiv.siblings(".hide")[0]).slideToggle('slow'); });
 .hide.hide { display: none; } .user-products.main { overflow-y: auto; } .user-product-details { margin-left: 50px; display: grid; grid-template-columns: repeat(3, 1fr); } .collapsible-header { margin-left: 50px; text-align: left; cursor: pointer; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="user-products main"> <div class="user-product"> <div class="collapsible-header"> <span class="user-product-expand-toggle"> <h4>&#9654; Product 1 - 2020-02-03 1:58pm</h4> </span> </div> <div class="hide"> <div class="user-product-details"> <div class="user-product-left"> <p>Download All Files as Zip</p> <p>View Preview</p> <p>Details</p> <p>Details</p> <p>Details</p> </div> <div class="user-product-mid"> <p>Details</p> <p>Details</p> <p>Details</p> <p>Details</p> <p>Details</p> </div> <div class="user-product-right"> <div class="unpurchased-product"><button class="purchase-product">Purchase</button></div> </div> </div> </div> </div> <div class="user-product"> <div class="collapsible-header"> <span class="user-product-expand-toggle"> <h4>&#9654; Product 2 - 2020-02-07 5:01pm</h4> </span> </div> <div class="hide"> <div class="user-product-details "> <div class="user-product-left"> <p>Download All Files as Zip</p> <p>View Preview</p> <p>Details</p> <p>Details</p> <p>Details</p> </div> <div class="user-product-mid"> <p>Details</p> <p>Details</p> <p>Details</p> <p>Details</p> <p>Details</p> </div> <div class="user-product-right"> <div class="unpurchased-product"><button class="purchase-product">Purchase</button></div> </div> </div> </div> </div> </div>

Wrap your div into another div .

 <div id="block_for_toggle"> <div style="display: grid"></div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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