AJAX 重新创建手风琴并打破它们

AJAX recreates accordions and breaks them

本文关键字:手风琴 新创建 创建 AJAX      更新时间:2023-09-26

我正在使用Search & Filter Pro来过滤网站上的图像。 我在手风琴中有一个复选框过滤器. 在页面加载时,一切正常。 问题是当我单击过滤器时,它使用 AJAX 重新创建过滤器并清除我的手风琴类.

搜索和过滤器带有几个钩子,一个在AJAX启动时运行,另一个在完成时运行。 当 AJAX 完成时,我可以重新运行手风琴脚本,但我丢失了哪个手风琴是打开的.

这是手风琴代码...

    ecg.accordions = ecg.accordions || {};
    ecg.accordions = {
        scrollToDiv: function(element){
            var offset = element.offset();
            var offsetTop = offset.top - 40;
            $('body,html').animate({
                        scrollTop: offsetTop
            }, 500);
        },
        init: function(){
            $('li[data-sf-field-type="taxonomy"]').not(':first').children('ul').hide();
            $('li[data-sf-field-type="taxonomy"]:first-child h4').addClass('expanded')
            $('li[data-sf-field-type="taxonomy"] h4').click(function(){
                if ($(this).hasClass('expanded')){
                    $(this)
                        .next()
                        .slideUp('fast');
                    $(this).removeClass('expanded');
                }else{
                    $('.expanded').each(function(){
                        $(this)
                            .next()
                            .slideUp('fast');
                        $(this).removeClass('expanded');
                    });                     
                    $(this)
                        .next()
                        .slideDown('fast', function(){
                            var el = $(this);
                            ecg.accordions.scrollToDiv(el);
                        });
                    $(this).addClass('expanded');
                }
                return false;
            });
        } // init
    } // ecg.accordions

以下是过滤器插件提供的钩子...

//detects the start of an ajax request being made
$(document).on("sf:ajaxstart", ".searchandfilter", function(){
    console.log("ajax start");
});
//detects when the ajax request has finished and the content has been updated
$(document).on("sf:ajaxfinish", ".searchandfilter", function(){
    console.log("ajax complete");
    ecg.accordions.init();
});

您可以在上面完成的事件中看到我重新运行手风琴代码。 我在想也许在 ajax 启动脚本中我得到了打开的手风琴并将其传递给完成的 ajax 事件,我不知道这是否可能.

下面是几个筛选器的示例标记

    <div class="filters">
       <form action="#" method="post" class="searchandfilter" data-sf-form-id="20" data-is-rtl="0" data-results-url="#" data-ajax-form-url="#" data-use-history-api="1" data-template-loaded="1" data-lang-code="" data-ajax="1" data-ajax-target=".listing" data-ajax-links-selector=".pagination a" data-update-ajax-url="1" data-only-results-ajax="1" data-scroll-to-pos="0" data-auto-update="1" data-auto-count="1" data-auto-count-refresh-mode="1" id="search-filter-form-20" autocomplete="off">
          <ul>
             <li class="sf-field-taxonomy-ce_venue" data-sf-field-name="_sft_ce_venue" data-sf-field-type="taxonomy" data-sf-field-input-type="checkbox">
                <h4>Venue</h4>
                <ul data-operator="or" class="">
                   <li class="sf-level-0 sf-item-39" data-sf-count="2">
                        <input  class="sf-input-checkbox" type="checkbox" value="ven1" name="_sft_ce_venue[]" id="sf-input-60a0def98ed13c6d6f9a27aee1c13e70">
                        <label class="sf-label-checkbox" for="sf-input-60a0def98ed13c6d6f9a27aee1c13e70">ven1<span class="sf-count">(2)</span></label>
                    </li>
                   <li class="sf-level-0 sf-item-42" data-sf-count="1">
                        <input  class="sf-input-checkbox" type="checkbox" value="ven2" name="_sft_ce_venue[]" id="sf-input-500ece294de752754740cc49b255a686">
                        <label class="sf-label-checkbox" for="sf-input-500ece294de752754740cc49b255a686">ven2<span class="sf-count">(1)</span></label>
                    </li>
                </ul>
             </li>
             <li class="sf-field-taxonomy-ce_color" data-sf-field-name="_sft_ce_color" data-sf-field-type="taxonomy" data-sf-field-input-type="checkbox">
                <h4>Color</h4>
                <ul data-operator="or" class="">
                   <li class="sf-level-0 sf-item-81" data-sf-count="2">
                        <input  class="sf-input-checkbox" type="checkbox" value="color1" name="_sft_ce_color[]" id="sf-input-39bf68813f58db9c7013a386ac7d5201">
                        <label class="sf-label-checkbox" for="sf-input-39bf68813f58db9c7013a386ac7d5201">color1<span class="sf-count">(2)</span></label>
                    </li>
                   <li class="sf-level-0 sf-item-43" data-sf-count="1">
                        <input  class="sf-input-checkbox" type="checkbox" value="color2" name="_sft_ce_color[]" id="sf-input-68bb548aeaab5440359a3afbdf9d9513">
                        <label class="sf-label-checkbox" for="sf-input-68bb548aeaab5440359a3afbdf9d9513">color2<span class="sf-count">(1)</span></label>
                    </li>
                </ul>
             </li>
          </ul>
       </form>
    </div>
我想到

的想法是记下哪个手风琴是打开的,这样我们就可以重新打开它,如果适用的话.

不要将事件处理程序直接应用于单个元素本身,而是依靠事件冒泡,因此我们只调用init一次。

所以:

        $('li[data-sf-field-type="taxonomy"] h4').click(function(){

成为:

        $('.filters').on('click', 'li[data-sf-field-type="taxonomy"] h4', function(){

激活手风琴时,我们可以"保存"对展开列表项的引用。对我来说,似乎<h4>的内容可以用来识别它们,所以我们将以它为例。

因此,在单击处理程序中,您有:

                $(this).addClass('expanded');

我们可以添加:

                var $h4 = $(this); // ...
                $h4.parents('.filters').data('reference', $h4.text());

我清理了代码,因此不必每次都生成查询对象($(this)),而是重用一个,例如 var $h4 = $(this); $h4.next().slideUp('fast'); //...

更新默认折叠面板以执行相同的操作,因此init具有:

        $('li[data-sf-field-type="taxonomy"]:first-child h4').addClass('expanded')

我们把它变成:

        var $first_h4 = $('li[data-sf-field-type="taxonomy"]:first-child h4');
        $first_h4.addClass('expanded').parents('.filter').data('reference', $first_h4.text());

然后更新搜索并筛选完整代码以利用以下内容:

//detects when the ajax request has finished and the content has been updated
$(document).on("sf:ajaxfinish", ".searchandfilter", function(){
    console.log("ajax complete");
    //ecg.accordions.init();
    // Loop through each filter, check if they had an expanded accordion, loop through the new h4's to see if there's match.
    $('.filters').each(function(){
        var $filter = $(this);
        var id     = $filter.data('reference');
        if (id) {
            $filter.find('li[data-sf-field-type="taxonomy"] h4:contains(' + id + ')').toggleClass('expanded', true);
        }
    });
});

如果您希望某些内容始终打开,例如通过init打开第一项,请将该代码放在其自己的函数中,并在搜索和过滤完成事件中重用它。需要一些调整,但是是的。