Завершая функцию аккордеона jQuery, я много пробовал, кажется, ничего не работает? - PullRequest
1 голос
/ 13 февраля 2020

Я сразу перейду к делу, я пытаюсь завершить этот эффект аккордеона (когда вы открываете один, другие закрываются), и на аккордеоне есть около 7 атрибутов. Каждый из них имеет знак ПЛЮС, поэтому, когда вы открываете его, он должен превратиться в знак МИНУС (через Font Awesome, эту часть я могу позаботиться, только для контекста).

HTML <a> содержит значок, который представляет собой знак + , а ul.checkbox-list - это то, что необходимо отслеживать на предмет наличия или отсутствия класса active, чтобы он мог свернуть другие. Я подобрался немного ближе, но потом случилось что-то еще, я подумал, что может помочь другой набор глаз?

    $(document).ready(function(){
        
        $("a[id^='attr']").on("click", function() {

            if( $(this + "ul.checkbox-list").hasClass("visible") ) {
                // Got lost as to what to do here ..
            } else {
                $("a[id^='attr'] > i").removeClass("fa-plus-circle").addClass("fa-minus-circle");
                $("ul.checkbox-list").removeClass("active");
                $(this).addClass("active");
                $("ul.checkbox-list").slideUp(200);
                $(this).siblings().slideDown("slow");
            }

        });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
        <section>
            <ul id="att7">
                <li>
                    <a href="#" id="attr7"><i class="fas fa-plus-circle"> </i> Lumens</a>
                    <ul class="checkbox-list">
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Aged Brass</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Antique Nickel</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Titanium</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Black & Aged Brass</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Titanium</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                    </ul>
                </li>    
            </ul> <!-- This is the last attribute in the accordion -->
        </section>
    </div>

РЕДАКТИРОВАТЬ: Гармошка (когда открыт, содержит флажки для вашего FYI).

Ответы [ 2 ]

1 голос
/ 13 февраля 2020

несколько ошибок в вашем коде:

# 1 $(this + "ul.checkbox-list") Вы можете просто сделать console.log(this), чтобы узнать, что this не строка, как + это аббревиатура для concat(), так как вы, скорее всего, в конечном итоге сделаете

$("[object HTMLDocument]ul.checkbox-list")

# 2 этот код

.slideUp(200).removeClass("active")

такой же, как

.removeClass("active").slideUp(200)

в качестве slide, как вы можете видеть из документации, является асинхронной c функцией, а не синхронной, поэтому она будет выполнять цепочку сразу, и не будет ждать ничего ... для удаления класс только после окончания анимации слайда, вам нужно будет передать его как обратный вызов

.slideUp(200, () => ...removeClass("..."))

# 3 вы проверяете класс visible, но во всем вашем коде, все, что вам нужно сделать, это обработать класс active вместо ...


В общем, я бы исправил и реорганизовал ваш код примерно так:

все строки объяснил для лучшего понимания

$(function() {
   $("a[id^='attr']").on("click", onClickLink);
});

function onClickLink(evt) {
  evt.preventDefault();                   // prevent browser to jump up
  var elm = $(evt.delegateTarget),        // the jquery traget elemnet
      chb = elm.next("ul.checkbox-list"), // the next ul.checkbox-list
      isActive = chb.hasClass("active");  // if the next element is active


  minimizeAll(() => {                     // reset to default position
    if(!isActive) maximizeGroup(elm);     // maximize only if the clicked elm is not active
  });
}

// minimize all elements
function minimizeAll(cb) {
  if($("ul.checkbox-list.active").length === 0 && cb)   // prevent slide up when all are minimized
    return cb();                                        // if callback is passed, use it

  $("a[id^='attr'] > i")                                // find all
    .addClass("fa-plus-circle")                         // add PLUS
    .removeClass("fa-minus-circle");                    // remove MINUS 
  $("ul.checkbox-list").slideUp("slow", () => {         // start sliding up
    $("ul.checkbox-list").removeClass("active");        // when sliding up ends, remove active class
    if(cb) cb();                                        // if callback is passed, use it
  });
}

// maximize only the element group
function maximizeGroup(elm) {
  elm.next("ul.checkbox-list").stop().slideDown(200, () => {  // STOP any previous animation and start sliding down the selected group
    elm.find("> i")                                    // from the clicked element (<a>) find (<i>)
        .removeClass("fa-plus-circle")                 // remove PLUS
        .addClass("fa-minus-circle");                  // add MINUS
    elm                                                // from the clicked element (<a>)
        .next("ul.checkbox-list")                      // select next ul.checkbox-list
        .addClass("active");                           // and add "active" class
  });
}
a[id^='attr'] {
    text-decoration: none;
    color: #333;
}
ul li {
  list-style: none;
}

/* default values */
ul ul {
  display: none; 
}
ul ul > li {
  display: flex; 
  flex-direction: row;
}

ul.checkbox-list.active {
    display: flex;
    flex-direction: column;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.1/css/all.css" integrity="sha384-v8BU367qNbs/aIZIxuivaU55N5GPF89WBerHoGA4QTcbUjYiLQtKdrfXnqAcXyTv" crossorigin="anonymous">

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


<div>
    <section>
        <ul id="att7">
            <li>
                <a href="#" id="attr7"><i class="fas fa-plus-circle"></i> Lumens 1</a>
                <ul class="checkbox-list">
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Aged Brass</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Antique Nickel</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Titanium</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Black &amp; Aged Brass</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Titanium</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                </ul>
            </li>    
        </ul> <!-- This is the last attribute in the accordion -->
    </section>
    <section>
        <ul id="att8">
            <li>
                <a href="#" id="attr8"><i class="fas fa-plus-circle"></i> Lumens 2</a>
                <ul class="checkbox-list">
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Aged Brass</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Antique Nickel</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Titanium</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Black &amp; Aged Brass</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                    <li> 
                        <div class="roundedTwo" style="">
                        <p>Titanium</p>
                        <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                        <label for="roundedTwo"></label>
                        </div>
                    </li>
                </ul>
            </li>    
        </ul> <!-- This is the last attribute in the accordion -->
    </section>
</div>
1 голос
/ 13 февраля 2020

В вашем коде множество ошибок. Прежде всего $(this + "ul.checkbox-list") не работает. Это элемент, вы не можете связать его с selecor. Используйте $(this).next("ul.checkbox-list"), чтобы найти следующий элемент (ЕСЛИ у него есть этот класс. Затем вы перепутали несколько случаев, показывая братьев и сестер et c. Ваш активный класс и видимый класс казались не связанными (хотя я предполагаю, что цель состояла в том, чтобы иметь один на кнопка другая в списке.) В коде, который я изменил, я сократил его до просто активного класса:

    $(document).ready(function(){
        
        $("a[id^='attr']").on("click", function(event) {
            event.preventDefault();
            if( $(this).next("ul.checkbox-list").hasClass("active") ) {
                $(this).next("ul.checkbox-list").slideUp(200).removeClass("active");
            } else {
                $("a[id^='attr'] > i").removeClass("fa-minus-circle").addClass("fa-plus-circle");
                $(this).find(" > i").removeClass("fa-plus-circle").addClass("fa-minus-circle");
                $("ul.checkbox-list").removeClass("active");
                $(this).siblings('ul.checkbox-list').slideUp("slow");
                $(this).next("ul.checkbox-list").slideDown(200).addClass("active");

            }

        });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<ul id="att7">
                <li>
                    <a href="#" id="attr7"><i class="fas fa-plus-circle"> </i> Lumens</a>
                    <ul class="checkbox-list active">
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Aged Brass</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Antique Nickel</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Titanium</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Black & Aged Brass</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                        <li style="display: flex; flex-direction: row;"> 
                            <div class="roundedTwo" style="">
                            <p>Titanium</p>
                            <input type="checkbox" value="None" id="roundedTwo" name="check" checked="">
                            <label for="roundedTwo"></label>
                            </div>
                        </li>
                    </ul>
                </li>    
            </ul> <!-- This is the last attribute in the accordion -->
        </section>
    </div>
...