2012-04-25 1 views
6

Я хотел бы получить все элементы/узлы на странице HTML, содержащие атрибуты, которые начинаются с чего-то (опять же, имена атрибутов начинаются с чего-то, а не с их значений!). Например, TinyMCE имеет тенденцию добавлять пользовательские атрибуты к сохраняемым им элементам, например "mce_style", "mce_href", "mce_bogus" и т. Д. Я хотел бы иметь что-то вроде селектора CSS3 для значений атрибутов, [attr^="mce_"], , но не для значений, имена атрибутов.Как получить все атрибуты HTML, которые начинаются с чего-то (имена атрибутов, * не * их значения!)

Конечно, я могу перебирать все узлы DOM и их атрибуты и проверять их один за другим, но мне было интересно, есть ли более эффективный способ.

Пожалуйста, не давайте мне ответы на TinyMCE, я уверен, что есть флаг, который предотвратит использование TinyMCE для этих атрибутов, но вопрос является общим.

+3

У меня такое ощущение, что вам придется либо перебирать каждый элемент, и просматривать каждый из атрибутов. Даже 'document.querySelectorAll()' не имеет параметра 'attribute-name-begin-with'. Интересный вопрос. –

+0

Я ничего не знаю о TinyMCE, но если есть способ идентифицировать элементы, у которых есть * любой * такой атрибут, тогда вы можете, по крайней мере, сузить свой поиск до подмножества, а затем посмотреть на каждый атрибут подмножества, который будет гораздо быстрее, чем смотреть на весь дом. То есть, есть ли какой-то атрибут, который всегда будет добавлен к одной из ваших целей? Если да, то сначала ищите это. –

+0

@jamietre Да, что касается TinyMCE, вы можете предположить, например. что 'mce_href' всегда будет применяться к элементам' a', поэтому вы можете сузить свой поиск. Но, как я сказал в последнем предложении, я не ищу ответы на TinyMCE, я бы предпочел иметь общее решение, и, судя по ответам, которые я получил до сих пор, нет другого пути, кроме как повторять все элементы и их атрибуты. Питти. – AsGoodAsItGets

ответ

-1

Попробуйте это: (Я пытался поставить * вместо a тега, но окрашена все элементы, в том числе тех, которые не имеют mce_style атрибут, а)

a[mce_style] { color : red; }​ 

Демо: http://jsfiddle.net/Tcdmb/

Дополнительная информация: https://developer.mozilla.org/en/CSS/Attribute_selectors

+4

Возможно, вы захотите перечитать вопрос ... – McGarnagle

+0

Хорошо. Это несколько решает его проблему, но не может использовать * или% в 'mce_ * 'для выбора всех элементов, имеющих атрибуты с' mce_' в качестве префикса. – codef0rmer

5

here's a simple demo найти все элементы, содержащие атрибут, начинающийся с mce_. могут потребоваться некоторые уточнения.

function getMCE() { 
    var el, attr, i, j, arr = [], 
     reg = new RegExp('^mce_', 'i'),    //case insensitive mce_ pattern 
     els = document.body.getElementsByTagName('*'); //get all tags in body 

    for (i = 0; i < els.length; i++) {     //loop through all tags 
     el = els[i]         //our current element 
     attr = el.attributes;       //its attributes 
     dance: for (j = 0; j < attr.length; j++) {  //loop through all attributes 
      if (reg.test(attr[j].name)) {    //if an attribute starts with mce_ 
       arr.push(el);       //push to collection 
       break dance;       //break this loop 
      } 
     } 
    } 
    return arr; 
} 

console.log(getMCE())​ 
+0

Да, это очевидное решение, итерация по всем элементам и их атрибутам, что слишком дорого для больших DOM. – AsGoodAsItGets

+1

+1 для 'break dance': D –

+0

-1 для' break dance', потому что он сломается по первому атрибуту элемента, который соответствует. Элемент может иметь несколько атрибутов соответствия. Но общий код выше, кажется, единственное решение на данный момент. – AsGoodAsItGets

1

Попробуйте это:

ФУНКЦИИ

//custom selector expression 
$.extend($.expr[':'],{ 
attr:function(o,i,m){ 
    var attrs=$.getAttrAll(o),re=m[3],found=false; 
    $.each(attrs,function(k,v){ 
    if(new RegExp(re).test(v)) { return found=true;} 
}); 
return found; 
} 
}); 
// get all atrributes of an element 
$.getAttrAll=function(el){ 
    var rect = []; 
    for (var i=0, attrs=el.attributes, len=attrs.length; i<len; i++){ 
    rect.push(attrs.item(i).nodeName); 
    } 
    return rect; 
}; 

` ИСПОЛЬЗОВАНИИ

// calling custom selector expression :attr(regexp) 
$(function(){ 
    $('body').find(':attr("^mce_")').css({background:'yellow'}); 
}); 

HTML

<body> 
    <p mce_style="height:50px" id="x" data-hello="hello">selected</p> 
    <div not_mce_bogus="abc">not_mce_bogus</div> 
    <div mce_href="http://rahenrangan.com">selected</div> 
    <p>othrs</p> 
</body> 
+0

Это в основном немного более элегантный, но я подозреваю, что немного менее эффективный, основанный на jQuery переписывание кода, опубликованного Джозефом ниже. Он все равно должен проходить через каждый элемент и каждый атрибут через DOM. Кроме того, пример использования, который вы упомянули, касается только непосредственных дочерних элементов тега body, правильное использование будет с помощью 'find()' вместо 'children()' (хотя в вашем простом HTML оно будет работать). Думаю, мне нужно жить с тем, что нет лучшего способа это сделать. – AsGoodAsItGets

+0

ya u r rite. благодаря –

1

Один из вариантов, если вы не возражаете, временно изменяя свой DOM, чтобы извлечь ваш HTML в строку и поиск атрибутов через RegExp. Когда вы найдете атрибуты, вы можете добавить «иглу» в DOM, чтобы вы могли использовать jQuery для выбора элементов.

Вот рабочая концепция (запустить с консоли открытым):

http://jsfiddle.net/skylar/N43Bm/

Код:

$.fn.extend({ 

    findAttributes: function(attribute) { 

     var attributeFinder = new RegExp(attribute + '(.+)="', "gi"); 
     var elementHTML = this.html().replace(attributeFinder, "data-needle='pin' "+attribute+"$1=\""); 

     this.html(elementHTML); 

     return this.find("[data-needle=pin]").removeAttr('data-needle'); 
    } 

}); 

console.log($("body").findAttributes('mce_')); 

Примечание: мое регулярное выражение не велика. Вы должны будете заботиться о чем-то лучше, чем в этом примере.

Смежные вопросы