2012-04-25 30 views
6

Me gustaría obtener todos los elementos/nodos en una página HTML que contenga atributos que comiencen con algo (una vez más, los nombres de atributos comienzan con algo, ¡no con sus valores!). Por ejemplo, TinyMCE tiene una tendencia de agregar atributos personalizados a los elementos que guarda, como "mce_style", "mce_href", "mce_bogus", etc. Me gustaría tener algo como el selector CSS3 para valores de atributo, [attr^="mce_"], pero no para los valores, el nombres de atributo.Cómo obtener todos los atributos HTML que comienzan con algo (los nombres de los atributos, * no * sus valores!)

Por supuesto, puedo iterar a través de todos los nodos DOM y sus atributos y verificarlos uno por uno, pero me pregunto si hay una manera más eficiente.

Por favor no me proporcione las respuestas específicas de TinyMCE, estoy bastante seguro de que hay una bandera que evitaría que TinyMCE guardara estos atributos, pero la pregunta es genérica.

+3

Tengo la sensación de que vas a tener que iterar a través de cada elemento y mirar a través de cada uno de los atributos. Incluso 'document.querySelectorAll()' no tiene una opción 'attribute-name-begins-with'. Interesante pregunta. –

+0

No sé nada sobre TinyMCE, pero si hay alguna forma de identificar elementos que tengan * any * tales atributos, entonces al menos puede limitar su búsqueda a un subconjunto primero, luego observe cada atributo del subconjunto, que sería mucho más rápido que mirar todo el dom. Es decir, ¿hay algún atributo que siempre se agregará a uno de tus objetivos? Si es así, busca eso primero. –

+0

@jamietre Sí, en lo que respecta a TinyMCE, puede asumir, por ejemplo, ese 'mce_href' siempre se aplicará a elementos' a', por lo que puede restringir su búsqueda. Pero como dije en la última oración, no estoy buscando respuestas específicas de TinyMCE, preferiría tener una solución genérica, y a juzgar por las respuestas que obtuve hasta ahora, no hay otra manera que iterar a través de todos los elementos y sus atributos Pitty. – AsGoodAsItGets

Respuesta

-1

Prueba esto: (He intentado poner * en lugar de a etiqueta pero coloreados todos los elementos, incluyendo aquellos que no tienen mce_style atribuyen así)

a[mce_style] { color : red; }​ 

Demostración: http://jsfiddle.net/Tcdmb/

Más información: https://developer.mozilla.org/en/CSS/Attribute_selectors

+4

Es posible que desee volver a leer la pregunta ... – McGarnagle

+0

Ok. Esto resuelve algo su problema, pero no puede usar * o% en 'mce_ * 'para seleccionar todos los elementos que tienen atributos con' mce_' como prefijo. – codef0rmer

5

here's a simple demo para encontrar todos los elementos que contienen un atributo que comienza con mce_. podría necesitar algunos refinamientos.

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

Sí, esta es la solución obvia, la iteración a través de todos los elementos y sus atributos, que es demasiado costoso para los DOM grandes. – AsGoodAsItGets

+1

+1 para 'break dance': D –

+0

-1 para' break dance' porque se romperá en el primer atributo de un elemento que coincida. Un elemento puede tener múltiples atributos coincidentes. Pero en general, el código anterior parece ser la única solución en este momento. – AsGoodAsItGets

1

Prueba esto:

FUNCIONES

//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; 
}; 

` USO

// 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

Esto es básicamente un poco más elegante, pero sospecho que es un poco menos eficaz, reescritura basada en jQuery del código publicado por Joseph a continuación. Todavía tiene que pasar a través de cada elemento y cada atributo a través del DOM. Además, el uso de ejemplo que mencionas solo considera los elementos secundarios de la etiqueta body, el uso correcto sería 'find()' en lugar de 'children()' (aunque en tu HTML simple funcionará). Creo que tengo que vivir con el hecho de que no hay mejor manera de hacerlo. – AsGoodAsItGets

+0

ya eres rito. Gracias –

1

Una opción, si no le importa temporalmente alterar su DOM, es extraer el código HTML en una cadena y la búsqueda de los atributos a través de RegExp. Cuando encuentre los atributos, puede agregar una "aguja" en el DOM para que pueda usar jQuery para seleccionar los elementos.

Aquí es un concepto de trabajo (correr con la consola abierta):

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

Código:

$.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_')); 

Nota: mi expresión regular no es muy grande. Tendrás que cuidar mejor que yo en este ejemplo.

Cuestiones relacionadas