Выберите теги, начинающиеся с " 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);
});

полный пример:

http://jsfiddle.net/6b8YY/3/

Примечания: (Обновлено, см. комментарии)

Если вам интересно, почему я использую этот способ для проверки имени тега, см.:
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);
});

тест см. Этот тест jsperf

обновление 2:

если вы хотите искать в документе, то вы можете сделать ниже, который является самым быстрым:

$(Array.prototype.slice.call(document.all)).filter(function () {
    return /^x-/i.test(this.nodeName);
}).each(function(){
    console.log(this.nodeName);
});

тест см. Этот тест jsperf


это может быть неэффективно, но рассмотрите его как последний вариант, если вы не получите никакого ответа.
Попробуйте добавить пользовательский атрибут к этим тегам. Я имею в виду, когда вы добавляете тег для 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 здесь.