我正在开发一个利用同位素布局来过滤 HTML 元素的项目。目前,我使用 jQuery 来实现过滤功能,但我想过渡到纯 vanilla JavaScript,以获得更好的性能和可维护性。
我尝试将 jQuery 代码转换为普通 JavaScript,但遇到错误。这是按预期工作的原始 jQuery 代码:
$(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;
});
});
下面的代码是普通的 JavaScript,但会抛出一些错误,包括这个错误
未捕获类型错误:无法读取 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;
});
}
});
有一些差异:
selector.classList.remove("active");
不是 jQuery 代码正在做的事情。后者这里指的不是selector
,而是过滤器下面的a
元素的集合。
您没有相当于
$(this).addClass('active');
的东西
filter = document.querySelectorAll('a');
不等同于 $filter.find('a')
。后者仅选择 a
元素 below $filter
,而您的翻译会获取所有这些元素,并覆盖 filter
- 忽略您之前存储在 filter
中的内容
第二个
itemSelector: '*'
与原来的filter: selector
不对应
不是问题,但你从不使用
iso
,所以我建议删除对该变量的赋值。
这是一个更正(假设
Isotope
构造函数是正确的):
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;
});
}
});