Выберите теги, начинающиеся с " x-" в jQuery
как я могу выбрать узлы, которые начинаются с "x-"
имя тега, вот пример дерева иерархии DOM:
<div>
<x-tab>
<div></div>
<div>
<x-map></x-map>
</div>
</x-tab>
</div>
<x-footer></x-footer>
jQuery не позволяет мне запрашивать $('x-*')
, есть ли способ, что я мог бы достичь этого?
9 ответов
нет собственного способа сделать это, у него худшая производительность, поэтому просто сделайте это сами.
пример:
var results = $("div").find("*").filter(function(){
return /^x\-/i.test(this.nodeName);
});
полный пример:
Примечания: (Обновлено, см. комментарии)
Если вам интересно, почему я использую этот способ для проверки имени тега, см.:
JavaScript: поиск без учета регистра
и СМ. комментарии также.
кроме того, если вам интересно о find
метод вместо добавления в селектор, поскольку селекторы сопоставляются справа, а не слева, может быть лучше отделить селектор. Я мог бы также сделать это:$("*", $("div"))
. Предпочтительно, хотя вместо просто div
добавьте идентификатор или что-то в него, чтобы родительское совпадение было быстрым.
в комментариях вы найдете доказательство того, что это не быстрее. Это относится к очень простым документам, хотя я считаю, где стоимость создание объекта jQuery превышает стоимость поиска всех элементов DOM. В реалистичных размерах страниц, хотя это не так.
обновление:
мне также очень нравится ответ Тейфи. Вы можете сделать это в одном месте, а затем использовать его везде. Например, позвольте мне смешать мой путь с его:
// In some shared libraries location:
$.extend($.expr[':'], {
x : function(e) {
return /^x\-/i.test(this.nodeName);
}
});
// Then you can use it like:
$(function(){
// One way
var results = $("div").find(":x");
// But even nicer, you can mix with other selectors
// Say you want to get <a> tags directly inside x-* tags inside <section>
var anchors = $("section :x > a");
// Another example to show the power, say using a class name with it:
var highlightedResults = $(":x.highlight");
// Note I made the CSS class right most to be matched first for speed
});
это тот же хит производительности, но более удобный API.
ниже просто работает нормально. Хотя я не уверен в производительности, поскольку я использую regex.
$('body *').filter(function(){
return /^x-/i.test(this.nodeName);
}).each(function(){
console.log(this.nodeName);
});
PS: В приведенном выше примере я рассматриваю body
- тег, как родительского элемента.
обновление :
после проверки сообщения Мохамеда Мелиги кажется, что регулярное выражение быстрее, чем манипуляция строками в этом состоянии. и это может стать быстрее (или же), если мы используем find
. Что-то вроде этого:--6-->
$('body').find('*').filter(function(){
return /^x-/i.test(this.nodeName);
}).each(function(){
console.log(this.nodeName);
});
обновление 2:
если вы хотите искать в документе, то вы можете сделать ниже, который является самым быстрым:
$(Array.prototype.slice.call(document.all)).filter(function () {
return /^x-/i.test(this.nodeName);
}).each(function(){
console.log(this.nodeName);
});
это может быть неэффективно, но рассмотрите его как последний вариант, если вы не получите никакого ответа.
Попробуйте добавить пользовательский атрибут к этим тегам. Я имею в виду, когда вы добавляете тег для eg. <x-tag>
, добавьте с ним пользовательский атрибут и назначьте ему то же значение, что и тег, поэтому html выглядит как <x-tag CustAttr="x-tag">
.
Теперь, чтобы получить теги, начиная с x-
, вы можете использовать следующий код jQuery:
$("[CustAttr^=x-]")
и вы получите все теги, которые начинаются с x-
пользовательский селектор jquery
jQuery(function($) {
$.extend($.expr[':'], {
X : function(e) {
return /^x-/i.test(e.tagName);
}
});
});
чем, использовать $(":X")
или $("*:X")
для выбора узлов.
хотя это не отвечает на вопрос напрямую, это может обеспечить решение, "определяя" теги в селекторе, вы можете получить все эти типы?
$('x-tab, x-map, x-footer')
решение: Если вы хотите эту вещь более одного раза, было бы намного эффективнее добавить класс на основе тега, который вы делаете только один раз в начале, а затем фильтруете для тега тривиальным способом.
Я имею в виду,
function addTagMarks() {
// call when the document is ready, or when you have new tags
var prefix = "tag--"; // choose a prefix that avoids collision
var newbies = $("*").not("[class^='"+prefix+"']"); // skip what's done already
newbies.each(function() {
var tagName = $(this).prop("tagName").toLowerCase();
$(this).addClass(prefix + tagName);
});
}
после этого вы можете сделать $("[class^='tag--x-']") или то же самое с querySelectorAll, и это будет достаточно быстро.
посмотрите, работает ли это!
function getXNodes() {
var regex = /x-/, i = 0, totalnodes = [];
while (i !== document.all.length) {
if (regex.test(document.all[i].nodeName)) {
totalnodes.push(document.all[i]);
}
i++;
}
return totalnodes;
}
var i=0;
for(i=0; i< document.all.length; i++){
if(document.all[i].nodeName.toLowerCase().indexOf('x-') !== -1){
$(document.all[i].nodeName.toLowerCase()).addClass('test');
}
}
попробуй такое
var test = $('[x-]');
if(test)
alert('eureka!');
в основном селектор jQuery работает как селектор CSS. прочитайте API селектора jQuery здесь.