互斥数据属性选择器

Mutually Exclusive Data Attribute Selectors

本文关键字:选择器 数据属性      更新时间:2023-09-26

是否可以根据互斥的数据属性选择元素,例如:我想要.show()任何具有country="united-kingdom"数据属性的div s,也具有type="partner""director" ?例如:

$('.post[data-country="united-kingdom"]&[data-type="partner,director"]').show();

$('.post[data-country="united-kingdom"]&[data-type="partner"]or[data-type="director"]').show();

我想。show()任何div的数据属性为country="united-kingdom"还有type="partner"或"director" ?

然后你需要一个选择器:

$('.post[data-country="united-kingdom"][data-type="partner"], .post[data-country="united-kingdom"][data-type="director"]').show();

表示匹配任何

的元素
  • 具有post类,data-country设置为united-kingdom, data-type设置为partner

  • post类,data-country设置为united-kingdom, data-type设置为director

"or"部分来自,,这使得它成为一个选择器组而不是单个选择器。


在评论中,你说:

用户可以选择10个或更多的分类法术语,这需要生成该条件的大量排列。

在这种情况下,您最好使用filter:

var countries = ["united-kingdom"];  // This would be created from inputs
var types = ["partner", "director"]; // This too
然后

var results = $(".post[data-country][data-type]").filter(function() {
    var $this = $(this);
    return countries.indexOf($this.attr("data-country") != -1 &&
           types.indexOf($this.attr("data-type") != -1;
});

在ES2016或更高版本,你可以使用Array#includes -它给你一个简单的布尔值-而不是Array#indexOf,你必须检查-1;你可以在ES2015或更早的版本中使用polyfill…

var results = $(".post[data-country][data-type]").filter(function() {
    var $this = $(this);
    return countries.includes($this.attr("data-country") &&
           types.includes($this.attr("data-type");
});

这甚至可以更进一步:

var criteria = {};
// From inputs, ...
criteria["country"] = ["united-kingdom"];
criteria["type"] = ["parter", "director"];
然后

var keys = Object.keys(criteria);
var selector= ".post" + keys.map(function(key) {
    return "[data-" + key + "]";
}).join();
var results = $(selector).filter(function() {
    var $this = $(this);
    return keys.every(function(key) {
        return criteria[key].includes($this.attr("data-" + key));
    });
});

只要我们考虑ES2015和ES2016:

const keys = Object.keys(criteria);
const results = $(selector).filter(() => {
    const $this = $(this);
    return keys.every(key => criteria[key].includes($this.attr("data-" + key)));
});

或者如果你真的想疯:

const keys = Object.keys(criteria);
const results = $(selector).filter(() =>
    keys.every(key => criteria[key].includes(this.getAttribute("data-" + key)))
);

可以添加以逗号分隔的多个选择器

$('.post[data-country="united-kingdom"][data-type="artist"], .post[data-country="united-kingdom"][data-type="partner"]').show();

或者使用带有选择器的过滤器

$('.post[data-country="united-kingdom"]').filter('[data-type="artist"], [data-type="partner"]').show();

或带有回调

的过滤器
var countries = ["united-kingdom", "india", "france"],
    types     = ["artist", "partner"];
$('.post').filter(function() {
    return types.indexOf( $(this).data('type') ) !== -1 &&
           contries.indexOf( $(this).data('coutry') ) !== -1;
}).show()