Проблемы с компоновкой изотопной сетки после фильтрации

Я изо всех сил пытаюсь найти хорошее решение, связанное с изотопом, фильтрами и сеткой. Проблема в том, что всякий раз, когда на моих элементах происходит фильтрация, изотоп использует то, что осталось, для определения макета сетки (на основе CSS). Итак, когда есть невидимые элементы, зажатые между видимыми, селекторы: nth-child, которые задают стиль сетке, включают те, которые искажают фактический стиль элементов. Вот видео об этой проблеме в действии: http://3cd.co/172n1C2f2k17

Так, например, у меня есть 6 элементов, если элемент № 2 удален, элемент № 3 должен быть № 2, а остальные отрегулированы соответствующим образом. Единственный способ, который я придумал, - это физически переместить невидимые элементы до конца, чтобы они не влияли на стиль видимых элементов. Затем я должен их сбросить, когда все будет пересортировано.

Я думаю, что, возможно, то, что у меня есть, в основном связано с событием. Единственное событие, которое я смог найти, чтобы исправить это arrangeComplete. Проблема в том, что Isotope уже определила свой макет к этому моменту, и это не решает проблему, поэтому мне нужно запустить $archive_grid.isotope('layout'), который будет отлично работать, за исключением того факта, что это происходит слишком быстро, и макет просто сходит с ума (см. Здесь : http://3cd.co/023R2e0i2d3n). Поэтому мне пришлось добавить тайм-аут, чтобы отложить событие.

Вот jsfiddle: https://jsfiddle.net/cfpjf5c7/

Есть ли лучший способ справиться с этим? Я боролся с этим и не могу придумать решения.

Это мое временное, несколько рабочее решение, но мне не нравится:

http://3cd.co/0F3h1V1x0P0P

Это основной код для этого (в событии готовности документа):

// Set an initial index for each element to retain their order
$('.archive-contents > article').each(function(i){
    $(this).attr('data-initial-index', i);
});

// init isotope
var $archive_grid = $('.archive-contents').isotope({
    itemSelector: 'article',
    layoutMode: 'fitRows'
});

// on arrangeComplete, find all the hidden elements and move them to the end, then re-layout isotope
$archive_grid.on('arrangeComplete', function(){
    var $last = $archive_grid.find('article:visible:last');
    $archive_grid.find('article:not(:visible)').insertAfter( $last );
    setTimeout( function(){
        $archive_grid.isotope('layout');
    }, 500 );
});

var isIsotopeInit = false;

function onHashchange() {
    // re-sort all elements based on their original index values
    $archive_grid.find('article').sort(function(a, b) {
        return + $(a).attr('data-initial-index') - + $(b).attr('data-initial-index');
    }).appendTo( $archive_grid );

    var hashFilter = getHashFilter(),
        isotopeFilter = hashFilter;

    if( isotopeFilter && isotopeFilter != 'all' )
        isotopeFilter = '.wh_team_category-' + isotopeFilter;
    else if( isotopeFilter == 'all' )
        isotopeFilter = '*';

    if ( !hashFilter && isIsotopeInit ) {
        return;
    }

    isIsotopeInit = true;
    // filter isotope
    $archive_grid.isotope({
        itemSelector: 'article',
        filter: isotopeFilter
    });

    // set selected class on button
    if ( hashFilter ) {
        $archive_filters.find('.active').removeClass('active');
        $archive_filters.find('[data-filter="' + hashFilter + '"]').addClass('active');
    }
}

$(window).on( 'hashchange', onHashchange );

// trigger event handler to init Isotope
onHashchange();

person solepixel    schedule 22.06.2017    source источник
comment
Можете ли вы воссоздать проблему в CodePen, чтобы мы могли что-нибудь попробовать?   -  person Louys Patrice Bessette    schedule 22.06.2017
comment
Ссылка или jsfiddle / codepen нужна, видео мало.   -  person Macsupport    schedule 23.06.2017
comment
Попробуйте это: jsfiddle.net/cfpjf5c7   -  person solepixel    schedule 23.06.2017


Ответы (1)


Я нашел решение, в котором я переместил скрытые элементы до Isotope Layout (во время фильтрации), поэтому не требуется 2 вызовов Layout. Незадолго до isIsotopeInit = true я добавил:

if( isotopeFilter != '*' ){
    var $last = $archive_grid.find( isotopeFilter ).last(),
        $hidden = $archive_grid.find('article').not( isotopeFilter );

    $hidden.insertAfter( $last );
}

Я в основном переместил содержимое обратного вызова arrangeComplete туда, где выполнялась фильтрация, и мне пришлось немного переписать его в зависимости от того, как фильтруются селекторы фильтров.

person solepixel    schedule 26.06.2017