jQuery es una mejor idea para agregar una clase activa al elemento del menú

Este sencillo script agrega una clase "activa" a un enlace en una lista cuando la URL de la página es = el atributo href del enlace.

var TheP   = window.location.pathname.split('/');
var HeRe   = TheP[TheP.length-1];
$('ul a').each(function(){
 var Link  = $(this).attr('href');
      if (Link == HeRe){ $(this).addClass('active');}
 });

Y funciona. Pero ... solo cuando el href el atributo es solo un archivo href="index.html". No funciona en absoluto en los siguientes casos o similares:

<a href="foo/index.html">foo</a>
<a href="../bar/index.html">bar</a>

En realidad, para solucionarlo, podría escribir:

 var TheP = window.location.pathname.split('/');
 var P1   = TheP[TheP.length-1];
 var P2   = TheP[TheP.length-2];
 var HeRe = P2+"/"+P1;

 $('ul a').each(function(){
  var Ln = $(this).attr('href');
  var Ln = Ln.split('/');
  var L1 = Ln[Ln.length-1];
  var L2 = Ln[Ln.length-2];
  var Link = L2+"/"+L1;
      if (Link == HeRe){$(this).addClass('active');}
 });

Pero ... ehm ... creo que debería haber una forma mejor y más flexible. También porque lo que está arriba no funciona con un solo archivo como ruta: (

preguntado el 10 de mayo de 11 a las 13:05

@user: Actualicé mi respuesta, entendí mal la pregunta al principio (aunque en realidad está escrita con bastante claridad). -

3 Respuestas

Noticias: Originalmente entendí mal la pregunta. Volviéndolo a leer, parece que quieres estar seguro no es para que coincida con todos index.htmls, pero solo en el específico en el que se encuentra (lo que tiene más sentido, en realidad).

En ese caso, puede hacer esto:

var path = window.location.href; // Just grabbing a handy reference to it
$('ul a').each(function() {
    if (this.href === path) {
        $(this).addClass('active');
    }
});

...porque el href propiedad (que es no es lo mismo que el atributo "href") del elemento DOM es el camino absoluto.

Ejemplo vivo

Obviamente, cuanto más pueda hacer para restringir ese selector inicial (dentro de lo razonable), mejor. Por ejemplo, si todo esto está dentro de alguna estructura de navegación, solo trabajar dentro de esa estructura será más eficiente.

Además, si habrá un montón de coincidencias, puede evitar hacer el contenedor jQuery al agregar la clase si lo desea:

    if (this.href === path) {
        this.className += " active"; // note the space
    }

Respuesta original:

Si la línea href los atributos siempre tendrán un / antes de la parte del nombre de archivo, entonces:

var TheP   = window.location.pathname.split('/');
var HeRe   = TheP[TheP.length-1];
$('ul a[href$="/' + HeRe + '"]').addClass('active');

Que usa un atributo termina con selector para encontrar los enlaces relevantes.

Si la línea href los atributos a veces pueden ser simplemente index.html o similar, puede hacer esto:

var TheP   = window.location.pathname.split('/');
var HeRe   = TheP[TheP.length-1];
$('ul a[href$="/' + HeRe + '"], ul a[href="' + HeRe + '"]').addClass('active');

... que atrapará a los que tienen / delante de ellos usando el selector "termina con", y también aquellos donde hay una coincidencia exacta usando el selector "igual".

contestado el 10 de mayo de 11 a las 18:05

J. ... gracias y perdón por mi inglés, he visto tu amable ejemplo en vivo y sí funciona. Pero no es útil si tiene hrefs como estos: href = "../A/index.html"o href ="../B/index.html"y así sucesivamente. Porque mis dos scripts funcionan, pero funcionan por separado. Me gustaría SÓLO UN script en su lugar, para que coincida con los hrefs correctos que tengan un menú con" index.html "y" foo.html "o" ../A /index.html "y" ../B/index.html "o incluso" ../A/B/index.html "y" ../B/B/index.html "donde las partes relevantes podrían ser diferentes . - Steve

@usuario: (Su inglés parece correcto). No estoy seguro de entender, la razón por la que estoy usando el href propiedad en lugar del atributo "href" es que no se sea ​​relativo. En el momento en que se analiza el DOM, si tiene un <a href="../A/index.html"> en una página en http://example.com/foo/B/nifty.html,la href propiedad en el elemento DOM para ese ancla será http://example.com/foo/A/index.html. El propiedad es una ruta absoluta completamente resuelta. Ya que comparamos eso con window.location.href, que también es una ruta absoluta, podemos usar ===. - TJ Crowder

En lugar de dividir el nombre de la ruta, ¿por qué no lo comparas todo? Si tiene URL relativas, debería ser fácil. Además, puede realizar un reemplazo para tratar con URL absolutas.

var mainpart = window.location.protocol + "//" + window.location.host;
var path = '/' + window.location.pathname;
$('ul a').each(function(){
    var Link  = $(this).attr('href').replace(mainpart, '');
    if (Link === path || '/' + Link === path){ $(this).addClass('active');}
});

contestado el 10 de mayo de 11 a las 18:05

Gracias, pero no es lo que necesito: / - Steve

var TheP = window.location.pathname.split('/');
var HeRe = TheP[TheP.length-1];
$('ul a[href$="' + HeRe + '"]').addClass('active');

Según especificación http://www.w3.org/TR/css3-selectors/#attribute-substrings :

Se proporcionan tres selectores de atributos adicionales para hacer coincidir las subcadenas en el valor de un atributo:

  • [att ^ = val] Representa un elemento con el atributo att cuyo valor comienza con el prefijo "val". Si "val" es la cadena vacía, entonces el selector no representa nada.
  • [att $ = val] Representa un elemento con el atributo att cuyo valor termina con el sufijo "val". Si "val" es la cadena vacía, entonces el selector no representa nada.
  • [att * = val] Representa un elemento con el atributo att cuyo valor contiene al menos una instancia de la subcadena "val". Si "val" es la cadena vacía, entonces el selector no representa nada.

contestado el 10 de mayo de 11 a las 18:05

.. enfoque interesante de los selectores CSS3. Pero usando [href * =] or [href $ =] obtendría demasiadas coincidencias. Piense en el escenario del menú con un href = "../ A / index.html" o href = "../ B / index.html" - Steve

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.