GoodnessGoodness Chi
GoodnessGoodness Chi

Reputation: 85

Converting jQuery Isotope Filtering Code to Vanilla JavaScript

I'm working on a project that utilizes Isotope Layout to filter HTML elements. Currently, I'm using jQuery to achieve the filtering functionality, but I'd like to transition to pure vanilla JavaScript for better performance and maintainability.

I've attempted to convert the jQuery code to vanilla JavaScript, but I'm encountering errors. Here's the original jQuery code that works as expected:

$(window).on('load', function() {
    var $container = $('.portfolioContainer');
    var $filter = $('#filter');
    $container.isotope({
        filter: '*',
        layoutMode: 'masonry',
        animationOptions: {
            duration: 750,
            easing: 'linear'
        }
    });
    $filter.find('a').click(function() {
        var selector = $(this).attr('data-filter');
        $filter.find('a').removeClass('active');
        $(this).addClass('active');
        $container.isotope({
            filter: selector,
            animationOptions: {
                animationDuration: 750,
                easing: 'linear',
                queue: false,
            }
        });
        return false;
    });
});
 

the code below is vanilla JavaScript but throw some errors including this one

Uncaught TypeError: Cannot read properties of undefined (reading 'remove') at HTMLAnchorElement.

document.addEventListener('DOMContentLoaded', function() {
    var container = document.querySelector('.portfolioContainer');
    var filter = document.getElementById('filter');

    var iso = new Isotope(container, {
        itemSelector: '*',
        layoutMode: 'masonry',
        animationOptions: {
            duration: 750,
            easing: 'linear'
        }
    });
    filter = document.querySelectorAll('a');
    for (var linkElement of filter) {
        linkElement.addEventListener('click', function(event) {
            var selector = event.target.getAttribute("data-filter");
            selector.classList.remove("active");
            var iso = new Isotope(container, {
                itemSelector: '*',
                layoutMode: 'masonry',
                animationOptions: {
                    duration: 750,
                    easing: 'linear'
                }
            });
            return false;
        });
    }
});

Upvotes: 0

Views: 234

Answers (1)

trincot
trincot

Reputation: 349964

There are a few differences:

  • selector.classList.remove("active"); is not what the jQuery code is doing. The latter does not refer to selector here, but the collection of a elements below the filter.

  • You don't have the equivalent of $(this).addClass('active');

  • filter = document.querySelectorAll('a'); is not the equivalent of $filter.find('a'). The latter only selects a elements below $filter, while your translation gets all of them, and overwrites filter -- ignoring what you had stored in filter before

  • The second itemSelector: '*' does not correspond to the original filter: selector

  • Not a problem, but you never use iso, so I'd suggest dropping the assignments to this variable.

Here is a correction (assuming the Isotope constructor is correct):

document.addEventListener('DOMContentLoaded', function() {
    const container = document.querySelector('.portfolioContainer');
    const filter = document.getElementById('filter');

    new Isotope(container, {
        itemSelector: '*',
        layoutMode: 'masonry',
        animationOptions: {
            duration: 750,
            easing: 'linear'
        }
    });
    const links = filter.querySelectorAll('a');
    for (const linkElement of links) {
        linkElement.addEventListener('click', function() {
            for (const link of links) {
                link.classList.toggle("active", linkElement === link);
            }
            new Isotope(container, {
                itemSelector: this.getAttribute("data-filter"),
                layoutMode: 'masonry',
                animationOptions: {
                    duration: 750,
                    easing: 'linear'
                }
            });
            return false;
        });
    }
});

Upvotes: 1

Related Questions