Preciso selecionar elementos com base nos valores armazenados no .data()
objeto de um elemento . No mínimo, gostaria de selecionar propriedades de dados de nível superior usando seletores, talvez assim:
$('a').data("category","music");
$('a:data(category=music)');
Ou talvez o seletor esteja no formato regular de seletor de atributos:
$('a[category=music]');
Ou no formato de atributo, mas com um especificador para indicar que está em .data()
:
$('a[:category=music]');
Eu achei a implementação de James Padolsey simples, mas boa. O seletor formata os métodos de espelhamento mostrados nessa página. Há também este patch Sizzle .
Por alguma razão, lembro de ler um tempo atrás que o jQuery 1.4 incluiria suporte para seletores de valores no .data()
objeto jquery . No entanto, agora que estou procurando, não consigo encontrá-lo. Talvez tenha sido apenas uma solicitação de recurso que eu vi. Existe suporte para isso e eu simplesmente não estou vendo?
Idealmente, eu gostaria de oferecer suporte a subpropriedades em data () usando a notação de ponto. Como isso:
$('a').data("user",{name: {first:"Tom",last:"Smith"},username: "tomsmith"});
$('a[:user.name.first=Tom]');
Também gostaria de oferecer suporte a vários seletores de dados, onde apenas elementos com TODOS os seletores de dados especificados são encontrados. O seletor múltiplo de jquery regular faz uma operação OR. Por exemplo, $('a.big, a.small')
seleciona a
tags com classe big
ou small
). Estou procurando um AND, talvez assim:
$('a').data("artist",{id: 3281, name: "Madonna"});
$('a').data("category","music");
$('a[:category=music && :artist.name=Madonna]');
Por fim, seria ótimo se operadores de comparação e recursos regex estivessem disponíveis nos seletores de dados. Então $(a[:artist.id>5000])
seria possível. Sei que provavelmente poderia fazer muito disso usando filter()
, mas seria bom ter um formato seletor simples.
Quais soluções estão disponíveis para fazer isso? O Padolsey de Jame é a melhor solução no momento? Minha preocupação é principalmente com relação ao desempenho, mas também aos recursos extras, como notação de ponto de subpropriedade e vários seletores de dados. Existem outras implementações que suportam essas coisas ou são melhores de alguma forma?
fonte
Respostas:
Eu criei um novo
data
seletor que deve permitir que você faça consultas aninhadas e condições AND. Uso:O padrão é:
"operator" e "check" são opcionais. Portanto, se você apenas o tiver
:data(a.b.c)
, simplesmente verificará a veracidade dea.b.c
.Você pode ver os operadores disponíveis no código abaixo. Entre eles está o
~=
que permite o teste de regex:Eu testei com algumas variações e parece funcionar muito bem. Provavelmente adicionarei isso como um repositório do Github em breve (com um conjunto de testes completo), então fique de olho!
O código:
fonte
$("a:data(condition),a:data(orCondition)")
... isso terá o mesmo efeito. Quanto mais recursos você adicionar, mais lento será. Se a lógica for complexa, use$(foo).filter(function(){...})
.jQuery.data
, que não obtém os dados definidos nos atributos HTML5. Se você deseja essa funcionalidade, pode mudarjQuery.data
para$('selector').data
, mas isso é uma troca de velocidade.No momento eu estou selecionando assim:
O que parece funcionar muito bem, mas seria bom se o jQuery pudesse selecionar por esse atributo sem o prefixo 'data-'.
Eu não testei isso com os dados adicionados aos elementos via jQuery dinamicamente, para que possa ser a queda desse método.
fonte
Você também pode usar uma função de filtragem simples sem nenhum plug-in. Não é exatamente isso que você deseja, mas o resultado é o mesmo:
fonte
filter
função de passagem poderia aceitar uma função de teste =) graçasQuero avisar que
$('a[data-attribute=true]')
não funciona, conforme a resposta de Ashley, se você anexou dados a um elemento DOM por meio da função data ().Funciona como seria de esperar se você adicionasse um atributo de dados real ao seu HTML, mas o jQuery armazena os dados na memória, para que os resultados obtidos
$('a[data-attribute=true]')
não sejam corretos.Você precisará usar o plug-in de dados http://code.google.com/p/jquerypluginsblog/ , usar a
filter
solução de Dmitri ou fazer $ .each sobre todos os elementos e verificar .data () iterativamentefonte
Existe um
:data()
plugin de filtro que faz exatamente isso :)Alguns exemplos com base em sua pergunta:
O desempenho não será muito bom comparado ao que é possível , selecionar
$._cache
e pegar os elementos correspondentes é de longe o mais rápido, mas muito mais abrangente e não muito "jQuery-ey" em termos de como você consegue coisas (você geralmente vem do lado do elemento). Do meu ponto de vista, não tenho certeza se isso é mais rápido, já que o processo de passar de um ID exclusivo para um elemento é complicado em si, em termos de desempenho.O seletor de comparação que você mencionou será o melhor a fazer em um
.filter()
, não há suporte interno para isso no plug-in, embora você possa adicioná-lo sem muitos problemas.fonte
data-*
atributos HTML5 e a seleção deles seriam mais rápidos do que a seleção de.data()
propriedades? Além disso, alguma idéia de onde posso descobrir mais sobre o cache $ ._? Eu pesquisei por isso, mas não estou encontrando muito.$.cache
não$._cache
, você pode ver como ele é implementado e usado no núcleo jQuery aqui: github.com/jquery/jquery/blob/master/src/data.js#L4 Quando você chama.data()
ele é realmente armazená-lo como um objeto in$.cache[elementUniqueID]
, que é um ID atribuído conforme necessário de maneira incremental para cada elemento, por exemplo, 1, 2, 3 etc. Esse ID de escalada será exposto no jQuery 1.4.3. Creio que, com base nos comentários do git no outro dia. Eu diria que a rota do HTML 5 seria mais rápida, depende das otimizações do navegador disponíveis (tenho certeza de que mais estarão disponíveis).Você pode definir um
data-*
atributo em um olmo usandoattr()
e selecione usando esse atributo:e agora para esse olmo, ambos
attr()
edata()
renderá 123 :No entanto, se você modificar o valor a ser 456 usando
attr()
,data()
ainda será 123 :Pelo que entendi, parece que você provavelmente deve evitar misturas
attr()
edata()
comandos no seu código, se não for necessário. Porqueattr()
parece corresponder diretamente ao DOM enquantodata()
interage com a 'memória', embora seu valor inicial possa ser do DOM. Mas o ponto principal é que os dois não estão necessariamente sincronizados.Portanto, tenha cuidado.
De qualquer forma, se você não estiver alterando o
data-*
atributo no DOM ou na memória, não terá problemas. Assim que você começa a modificar os valores, é possível que surjam problemas em potencial.Obrigado a @Clarence Liu à resposta de @ Ash, bem como a este post .
fonte
Funciona. Consulte Seletor de Igual ao Atributo [nome = ”valor”] .
fonte
Se você também usa o jQueryUI, obtém uma versão (simples) do
:data
seletor que verifica a presença de um item de dados, para que você possa fazer algo como$("div:data(view)")
, ou$( this ).closest(":data(view)")
.Consulte http://api.jqueryui.com/data-selector/ . Não sei há quanto tempo eles têm, mas está lá agora!
fonte
Aqui está um plugin que simplifica a vida https://github.com/rootical/jQueryDataSelector
Use-o assim:
fonte