Using jQuery's slidedown() and slideup() methods to achieve an accordion effect is very simple.

Its function is to adjust the height of the selected element with the effect of animation, so that it presents a "sliding" effect, while other attributes of the element do not change; the parameter speed is the speed of animation display, and the option [callback] is the callback function executed after the completion of animation display.

If CSS3 is used to achieve this effect, there are five features to be realized and five problems to be solved:

  1. Dynamically adjust the display area with the animation effect of "sliding"
  2. No height is set for the selected element, and its height is adaptive by the number of sub elements
  3. It can adjust the display area without occupying the position
  4. The animation display speed can be adjusted by parameters
  5. Optional [callback] is the callback function executed after the completion of animation display

With the problem identified, I'm ready to start with building a panel.

    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <style>
                .panel {
                    margin-bottom: 20px;
                    background-color: #fff;
                    border: 1px solid #ddd;
                }

                .panel-heading {
                    cursor:pointer;
                    color: #333;
                    background-color: #f5f5f5;
                    padding: 10px 15px;
                    border-bottom: 1px solid  #ddd;
                }

                .panel-title {
                    margin-top: 0;
                    margin-bottom: 0;
                    font-size: 16px;
                }

                .panel-body {
                    padding: 15px;
                }
            </style>
        </head>
        <body>
            <div class="panel">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    <p>Panel content</p>
                    <p>Panel content</p>
                    <p>Panel content</p>
                    <p>Panel content</p>
                </div>
            </div>
        </body>
    </html>
    

After building the panel, according to jQuery, I am ready to dynamically adjust the panel height to achieve the effect I need. Through the learning of CSS3, we know that animation can be realized by setting the transition attribute transition, so I wrote CSS as follows:

    .panel-heading {
        border-bottom: 0;
    }

    .panel-body {
        padding: 0px;
        height: 0px;
        overflow:hidden;
        transition: height .6s;
        -moz-transition: height .6s;
        -webkit-transition: height .6s;
        -o-transition: height .6s;
    }

    .panel:hover .panel-body {
        padding: 15px;
        height:auto;
    }

    .panel:hover .panel-heading {
        border-bottom: 1px solid  #ddd;
    }

I believe that the students who have tried to do this already know that there is no effect, and the effect of display and hiding is realized, but there is no animation effect, and in order to completely hide the panel body, it is not what I want to forcibly set its padding value!

This is the first pit I stepped on. I believe those students who are trying to achieve this effect will step on this pit. I have seen the example in w3school. In the example, the width of the selected element is dynamically adjusted. At that time, I thought that the height value was ok, but I found it was not. So I looked up the data and found that there are two ways to realize problem 1

  1. Wrap a div around the selected element by setting the max height of div: 0px to 999px
  2. Wrap a div around the selected element, and set the transform: translatey (- 100%) to translatey (0) of the selected element by setting the overflow: hidden of the Div

It is worth noting that 999px set in method 1 depends on the situation, as long as the maximum height is greater than the estimated height, while method 2 can realize problem 1 and problem 2 , but cannot realize problem 3 .

Through the above summary, I wrapped a panel collapses outside the panel bady to implement the panel's sidetoggle.

    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <style>
                .panel {
                    margin-bottom: 20px;
                    background-color: #fff;
                    border: 1px solid #ddd;
                }

                .panel-heading {
                    cursor:pointer;
                    color: #333;
                    background-color: #f5f5f5;
                    padding: 10px 15px;
                    border-bottom: 1px solid  #ddd;
                }

                .panel-title {
                    margin-top: 0;
                    margin-bottom: 0;
                    font-size: 16px;
                }

                .panel-body {
                    padding: 15px;
                }

                .panel-heading {
                    border-bottom: 0px;
                }

                .panel-collapse {
                    overflow:hidden;
                    max-height: 0px;
                    transition: max-height .6s;
                    -moz-transition: max-height .6s;
                    -webkit-transition: max-height .6s;
                    -o-transition: max-height .6s;
                }

                .panel:hover .panel-collapse {
                    max-height: 200px;
                }

                .panel:hover .panel-heading {
                    border-bottom: 1px solid  #ddd;
                }
            </style>
        </head>
        <body>
            <div class="panel">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-collapse">
                    <div class="panel-body">
                        <p>Panel content</p>
                        <p>Panel content</p>
                        <p>Panel content</p>
                        <p>Panel content</p>
                    </div>
                </div>
            </div>
        </body>
    </html>

Ha ha, so we have realized the effect of jQuery's slide animation sildedown() and slideup(). Did you copy several more panels to achieve the accordion effect soon?

So I changed the code slightly, such as:

    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <style>
                .panel {
                    margin-bottom: 20px;
                    background-color: #fff;
                    border: 1px solid #ddd;
                }

                .panel-heading {
                    cursor:pointer;
                    color: #333;
                    background-color: #f5f5f5;
                    padding: 10px 15px;
                    border-bottom: 1px solid  #ddd;
                }

                .panel-title {
                    margin-top: 0;
                    margin-bottom: 0;
                    font-size: 16px;
                }

                .panel-body {
                    padding: 15px;
                }

                .panel-group {
                    width: 300px;
                    margin: 0 auto;
                }

                    .panel-group .panel {
                        margin:5px;
                    }

                .panel-group .panel-heading {
                    border-bottom: 0;
                }

                    .panel-group .panel-heading + .panel-collapse > .panel-body {
                        border-top: 1px solid #ddd !important;
                    }

                .panel-collapse {
                    max-height: 0px;
                    overflow-y: auto;
                    transition: max-height .6s;
                    -moz-transition: max-height .6s;
                    -webkit-transition: max-height .6s;
                    -o-transition: max-height .6s;
                }

                .panel:hover > .panel-collapse {
                    max-height: 100px;
                }
            </style>
        </head>
        <body>
            <div class="panel-group">
                <div class="panel">
                    <div class="panel-heading">
                        <h3 class="panel-title">Panel title</h3>
                    </div>
                    <div class="panel-collapse">
                        <div class="panel-body">
                            <p>Panel content</p>
                        </div>
                    </div>
                </div>
                <div class="panel">
                    <div class="panel-heading">
                        <h3 class="panel-title">Panel title</h3>
                    </div>
                    <div class="panel-collapse">
                        <div class="panel-body">
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                        </div>
                    </div>
                </div>
                <div class="panel">
                    <div class="panel-heading">
                        <h3 class="panel-title">Panel title</h3>
                    </div>
                    <div class="panel-collapse">
                        <div class="panel-body">
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                        </div>
                    </div>
                </div>
            </div>
        </body>
    </html>

Yes, I have achieved the accordion effect, which is only half of it, because the above dynamic effects can only be expanded when hover is used, and can't be continued!

I think we should not only keep the deployment, but also ensure that the deployment effect of each panel is exclusive. Only Radio + label can achieve this effect!

Implementation ideas:

  1. Use radio to distinguish States, and use label to associate radio selection
  2. Find the selected element through CSS3 pseudo class selector element1 ~ Element2 selector

Final code:
    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <style>
                .panel {
                    margin-bottom: 20px;
                    background-color: #fff;
                    border: 1px solid #ddd;
                }

                .panel-heading {
                    cursor:pointer;
                    color: #333;
                    background-color: #f5f5f5;
                    padding: 10px 15px;
                    border-bottom: 1px solid  #ddd;
                }

                .panel-title {
                    margin-top: 0;
                    margin-bottom: 0;
                    font-size: 16px;
                }

                .panel-body {
                    padding: 15px;
                }

                .panel-group {
                    width: 300px;
                    margin: 0 auto;
                }

                    .panel-group .panel {
                        margin:5px;
                    }

                .panel-group .panel-heading {
                    border-bottom: 0;
                    display:block;
                }

                    .panel-group .panel-heading + .panel-collapse > .panel-body {
                        border-top: 1px solid #ddd !important;
                    }

                    .panel-group input[type="radio"] {
                        position:absolute;
                        display:none;
                    }

                .panel-collapse {
                    max-height: 0px;
                    overflow-y: auto;
                    transition: max-height .6s;
                    -moz-transition: max-height .6s;
                    -webkit-transition: max-height .6s;
                    -o-transition: max-height .6s;
                }    

                input[type="radio"]:checked ~  .panel-collapse {
                    max-height: 100px;
                }
            </style>
        </head>
        <body>
            <div class="panel-group">
                <div class="panel">
                    <input type="radio" name="panels" id="panel1" checked="checked">
                    <label class="panel-heading" for="panel1">
                        <h3 class="panel-title">Panel title</h3>
                    </label>
                    <div class="panel-collapse">
                        <div class="panel-body">
                            <p>Panel content</p>
                        </div>
                    </div>
                </div>
                <div class="panel">
                    <input type="radio" name="panels" id="panel2">
                    <label class="panel-heading" for="panel2">
                        <h3 class="panel-title">Panel title</h3>
                    </label>
                    <div class="panel-collapse">
                        <div class="panel-body">
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                        </div>
                    </div>
                </div>
                <div class="panel">
                    <input type="radio" name="panels" id="panel3">
                    <label class="panel-heading" for="panel3">
                        <h3 class="panel-title">Panel title</h3>
                    </label>
                    <div class="panel-collapse">
                        <div class="panel-body">
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                            <p>Panel content</p>
                        </div>
                    </div>
                </div>
            </div>
        </body>
    </html>

So far, the remaining two questions 4 and question 5 of the above five questions are not problems. The question 4 can be displayed frequently by setting transition duration. Of course, the transition timing function can also be set to specify the time curve of transition effect. Since question 5 requires [callback], it can only be supported by JavaScript, which can be obtained by listening to the transionend event of the selected element.

    var panels = document.getElementsByClassName('panel-collapse')
    for (var i = 0; i < panels.length; i++) {
        panels[i].addEventListener('transitionend', function () {
            Console. Log (arguments) / / get related element information through arguments
        })
    }

Related information: < br >
CSS3 transform 属性

CSS [attribute~=value] 选择器

All Comments

Leave a Reply Cancel Reply

Tips: Your email address will not be disclosed!

If you can't see clearly,please click to change...

Popular Posts

Collections