2011-12-21 18 views
8

Necesito generar selector css único para los elementos.
Particularmente, tengo un controlador de eventos onclick que debe recordar en qué elemento de destino se hizo clic en y enviar esta información a mi servidor. ¿Hay alguna manera de hacerlo sin hacer modificaciones DOM?¿Cómo generar selector css único para el elemento DOM?

P.S. mi código javascript se supone que se ejecuta en diferentes sitios web de terceros de
, por lo que no puedo hacer ninguna suposición sobre html.

+1

¿Puede dar el html es necesario seleccionar el elemento en? –

+0

en realidad, no tengo "mi" html porque mi código de JavaScript está insertado en algunos sitios web de terceros, por lo que el código html tiene una estructura arbitraria – tsds

+0

¿Y qué pasa con el código JS? – Miquel

Respuesta

1

Digamos que usted tiene una lista de enlaces para el bien de la sencillez: sólo tiene que pasar el índice del elemento desencadenante de la colección de todos los elementos

<a href="#">...</a> 
<a href="#">...</a>  
<a href="#">...</a> 

el js (jQuery 1.7+, que utiliza .on() utilizar de otra manera la función bind()) puede ser

var triggers = $('a'); 
triggers.on('click', function(e) { 
    e.preventDefault(); 
    var index = triggers.index($(this)); 
    /* ajax call passing index value */ 
}); 

por lo que si hace clic en el tercer elemen t valor de índice pasado será 2. (índice basado en 0); , por supuesto, esto es válido siempre que el código (el DOM) no cambie. Más tarde, puede usar ese índice para crear una regla CSS en ese elemento, p. utilizando :nth-child

De lo contrario, si cada uno de sus elementos tienen un atributo diferente (como un id) que puede pasar ese atributo

ejemplo en jsFiddle: http://jsfiddle.net/t7J8T/

+0

Esta es una solución simplista para un problema bastante complejo: la generación de selectores de CSS únicos que, en el mejor de los casos, son algo robustos a los cambios en la estructura de la página. Hay más de 10 bibliotecas que generan selectores de CSS, y el autor de una de ellas ha publicado [esta comparación] (https://github.com/fczbkk/css-selector-generator-benchmark). –

+0

@Dan Dascalescu: Desafortunadamente, los selectores en sí no proporcionan mucho para resolver ese problema. Además de los selectores de identificación y clase, casi todo lo demás en Selectores está estrechamente vinculado a la estructura del documento por diseño. El único selector que puede construir que identificaría de manera única un elemento independientemente de la estructura es un selector de id único, e incluso eso supone que el documento es conforme. (No estoy seguro si: root garantiza un elemento único en un documento conforming, pero si lo hace, sería solo otro selector que lo hace, y no uno particularmente útil.) – BoltClock

1

Probablemente podría atravesar el árbol DOM desde el nodo de nuevo al elemento del cuerpo para generar un selector.

Firebug tiene una función para esto, tanto con los selectores XPath y CSS.

Ver this answer

+0

¿Puede sugerir alguna biblioteca javascript que proporcione dicha funcionalidad? – tsds

+1

@tsds: hay más de 10 bibliotecas que generan selectores de CSS, y el autor de una de ellas ha publicado [esta comparación] (https://github.com/fczbkk/css-selector-generator-benchmark). –

3

Sí, se puede hacer esto. Pero con algunas advertencias. Para poder garantizar que los selectores sean únicos, debe usar :nth-child(), que no es universalmente compatible. Si luego quieres poner estos selectores de CSS en archivos CSS, no funcionará en todos los navegadores.

lo haría con algo como esto:

function() { 
    if (this.id) { 
     return sendToServer('#' + this.id); 
    } 
    var parent = this.parentNode; 
    var selector = '>' + this.nodeName + ':nth-child(' + getChildNumber(this) ')'; 
    while (!parent.id && parent.nodeName.toLowerCase() !== 'body') { 
     selector = '>' + this.nodeName + ':nth-child(' + getChildNumber(parent) + ')' + selector; 
     parent = parent.parentNode; 
    } 
    if (parent.nodeName === 'body') { 
     selector = 'body' + selector; 
    } else { 
     selector = '#' + parent.id + selector; 
    } 
    return sendToServer(selector); 
} 

A continuación, añadir que a su controlador de clic para cada elemento que se desea modelar. Lo dejo para implementar getChildNumber().

Editar: Sólo visto su comentario acerca de que sea tercera parte de código ... por lo que podría añadir un argumento event, reemplazar todas las instancias de this con event.target y luego simplemente conecte la función de window 's evento de clic si eso es más fácil.

+1

Generando selectores CSS únicos que idealmente son algo robustos a los cambios en la estructura de la página es un problema complejo. Hay más de 10 bibliotecas que generan selectores de CSS, y el autor de una de ellas ha publicado [esta comparación] (https://github.com/fczbkk/css-selector-generator-benchmark). –

1
"use strict"; 
function getSelector(_context){ 
    var index, localName,pathSelector, that = _context, node; 
    if(that =='null') throw 'not an dom reference'; 
    index = getIndex(that); 

    while(that.tagName){ 
     pathSelector = that.localName+(pathSelector?'>'+pathSelector :''); 
     that = that.parentNode; 
    } 
    pathSelector = pathSelector+':nth-of-type('+index+')'; 

    return pathSelector; 
} 

function getIndex(node){ 
    var i=1; 
    var tagName = node.tagName; 

    while(node.previousSibling){ 
    node = node.previousSibling; 
     if(node.nodeType === 1 && (tagName.toLowerCase() == node.tagName.toLowerCase())){ 
      i++; 
     } 
    } 
    return i; 
} 
document.addEventListener('DOMContentLoaded', function(){ 
    document.body.addEventListener('mouseover', function(e){ 
    var c = getSelector(e.target); 
     var element = document.querySelector(c); 
      //console.log(element); 
     console.log(c); 
     //element.style.color = "red" 

    }); 
}); 

puede probar este. sin usar jquery.

+0

El uso de selectores de tipo 'n-ésimo' y de ignorar identificadores hace que un selector sea menos robusto a los cambios en la estructura de la página. Este problema puede parecer simple, pero en realidad es un poco más complejo, ya que genera selectores de CSS únicos que, en el mejor de los casos, son algo robustos a los cambios en la estructura de la página. Hay más de 10 bibliotecas que generan selectores de CSS, y el autor de una de ellas ha publicado [esta comparación] (https://github.com/fczbkk/css-selector-generator-benchmark). –

1

Comprobar esta biblioteca generador de selector CSS @medv/finder

Build Status

  • Genera selectores más cortos
  • selectores exclusivos por página
  • estable y robusto selectores
  • 2,9 kB gzip y tamaño Minify

Ejemplo de selector generada:

.blog > article:nth-child(3) .add-comment 
Cuestiones relacionadas