jQuery Blues: 6.Selector contextual this

Tutorial de jQuery 6. En esta entrada veremos cómo hacer una selección por contexto mediante this.

klimt

archivado en: JavaScript / 13 noviembre, 2012 / taller:

Seguimos con el tutorial de jQuery. En la próxima entrada aprenderemos a desarrollar efectos muy chulos con muy poco código, pero antes es importante que profundicemos un poco más en los selectores, piedra angular de esta librería.

En el artículo anterior vimos cómo realizar una barra de navegación ocultando y mostrando los elementos <li> de una lista <ul>. Como solo eran tres bloques, no pasaba nada si como selector se utilizaba el identificador (id) de cada <ul>.

  • jQuery("#bloque_1").hover(
  • function(){
  • jQuery("#bloque_1 li ~li").css("display", "block");
  • },
  • function(){
  • jQuery("#bloque_1 li ~li").css("display", "none");
  • }
  • );

Pero esta no es la mejor manera de seleccionar los elementos, ya que obliga a escribir tres veces una función que hace lo mismo, una para cada bloque. Es más, hay muchas ocasiones en las que ni siquiera sabremos cuántos elementos tendremos que manejar, como ocurre con cualquier página que se genera dinámicamente, tal que hace WordPress.

Por lo tanto, es mejor si se declara el selector de forma dinámica, es decir, en vez de definirlo de antemano, vamos a especificar en cada momento que sea el elemento sobre el que está actuando el usuario.

Por ejemplo, si tenemos una página con dos párrafos:

  • <p> Soy el párrafo 1 </p>
  • <p> Soy el párrafo 2 </p>

Y queremos que al pasar el ratón sobre cada uno de ellos se cambie el color de fondo, según habíamos visto, tendríamos que añadirles sendos identificadores para luego seleccionarlos por jQuery.

  1. <!DOCTYPE html>
  2. <html>
  3. <meta charset="UTF-8">
  4. <head>
  5. <title>
  6. Ejemplo This
  7. </title>
  8. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
  9. <script type="text/javascript">
  10. $.noConflict();
  11. jQuery(document).ready(function($) {
  12. jQuery("#parrafo1").hover(
  13. function(){
  14. jQuery("#parrafo1").css("background-color", "#c00");
  15. },
  16. function(){
  17. jQuery("#parrafo1").css("background-color", "#fff");
  18. }
  19. );
  20. jQuery("#parrafo2").hover(
  21. function(){
  22. jQuery("#parrafo2").css("background-color", "#c00");
  23. },
  24. function(){
  25. jQuery("#parrafo2").css("background-color", "#fff");
  26. }
  27. );
  28. });
  29. </script>
  30. </head>
  31. <body>
  32. <p id="parrafo1"> Soy el párrafo 1 </p>
  33. <p id="parrafo2"> Soy el párrafo 2 </p>
  34. </body>
  35. </html>

¿Qué sucedería si tuviéramos 200 párrafos? ¿Habría que escribir 200 funciones, una para cada párrafo?  😎

No, no sería necesario porque jQuery permite seleccionar elementos por el contexto. La forma más habitual para eso es utilizando la palabra reservada this, que en inglés significa «este».

Mediante this podemos acotar la selección indicándolo en el selector tras poner una coma. Es como decirle a jQuery, no, no queremos que el evento afecte a todos los párrafos, sino solo a  «este» párrafo. Y luego, en vez de indicar el cambio a todos los párrafos, especificamos que sea solo a «este», a this.


<script type="text/javascript">
$.noConflict();
jQuery(document).ready(function($) {
jQuery("p", this).hover(
function(){
jQuery(this).css("background-color", "#c00");
},
function(){
jQuery(this).css("background-color", "#fff");
}
);
});
</script>

En el ejemplo anterior hemos aplicado el efecto del hover sobre el mismo elemento que usamos como selector <p>, pero mediante this también podemos seleccionar cualquier otro siguiendo la sintaxis que ya conocemos.

Por ejemplo, si tenemos un párrafo que contiene un <span>:

  • <p> Soy el párrafo <span> 1 </span> </p>
  • <p> Soy el párrafo <span> 2 </span> </p>

Y solo queremos que cambie el color del número, lo que está dentro del <span> al pasar el cursor, bastaría con delimitar ese efecto por contexto mediante this.

  • jQuery("p", this).hover(
  • function(){
  • jQuery("span", this).css("color", "#c00");
  • },
  • function(){
  • jQuery("span", this).css("color", "#000");
  • }
  • );

Práctica: menú seleccionado

Oki doki, pues vamos a terminar de aprender a emplear el selector this con un ejercicio, una barra de navegación en la que se quede marcada la opción seleccionada, lo cual permite comprender intuitivamente dónde te encuentras cuando estás navegando por una página.

En esta ocasión, en vez de emplear el método .css que veníamos usando hasta ahora, vamos a utilizar los métodos para añadir o quitar clases dinámicamente, que son:

Lo primero es realizar el menú, que ya sabemos cómo hacerlo flotando los <li> para que quede horizontal. En el menú vamos a indicar que cuando se pase el cursor sobre un elemento, en vez de un fondo rojo, se ponga negro. Algo así.

[singlepic id=22 w=308 h=42 float=center]

  • <!DOCTYPE html>
  • <html>
  • <meta charset="UTF-8">
  • <head>
  • <title>
  • Ejercicio menú seleccionado
  • </title>
  • <style type="text/css">
  • #menu ul{
  • list-style-type:none;
  • list-style-type:none;
  • padding:0em;
  • width:8em;
  • }
  • #menu li {
  • padding:0.3em;
  • float: left;
  • cursor: pointer;
  • }
  • .enlace_sin_seleccionar {
  • border-right: 1px solid #900;
  • border-left: 1px solid #f33;
  • background-color:#c00;
  • font-weight:bold;
  • color:#fff;
  • }
  • .enlace_sin_seleccionar:hover {
  • border-right: 1px solid #666;
  • border-left: 1px solid #ccc;
  • background-color:#000;
  • }
  • .enlace_seleccionado {
  • border-right: 1px solid #999;
  • border-left: 1px solid #ccc;
  • background-color:#000;
  • font-weight:bold;
  • color:#fff;
  • }
  • </style>
  • </head>
  • <body>
  • <ul id="menu">
  • <li class="enlace_sin_seleccionar">Opción 1</li>
  • <li class="enlace_sin_seleccionar">Opción 2</li>
  • <li class="enlace_sin_seleccionar">Opción 3</li>
  • <li class="enlace_sin_seleccionar">Opción 4</li>
  • </ul>
  • </body>
  • </html>

Observa que tenemos una clase, «.enlace_seleccionado», con los mismos estilos de la pseudo-clase «.enlace_sin_seleccionar:hover», que es la que define el rollover.

Entonces, es tan sencillo como decir que al seleccionar un botón quite la clase por defecto de ese elemento <li>, que es «.enlace_sin_seleccionar», y en su lugar ponga «.enlace_seleccionado»; pero, además, necesitamos que quite el «.enlace_seleccionado» del elemento que lo tenía, por lo que antes removemos esa clase de todos los elementos <li> del contenedor #menu y, en su lugar, dejamos la clase sin seleccionar. Algo así:

  • jQuery(document).ready(function($) {
  • jQuery("#menu li", this).click(function() {
  • jQuery("#menu li").removeClass("enlace_seleccionado");
  • jQuery("#menu li").addClass("enlace_sin_seleccionar");
  • jQuery(this).removeClass("enlace_sin_seleccionar");
  • jQuery(this).addClass("enlace_seleccionado");
  • });
  • });

Bueno, en realidad esta barra de navegación, de momento, solo nos valdría para un menú con tabuladores, dentro de la misma página, pero espero que nos haya servido para entender cómo se selecciona un elemento por contexto y cómo se añaden y quitan clases.

El próximo día más, de momento, os propongo un ejercicio:

Hacer una página con 3 preguntas y sus respectivas respuestas, que no se verán (estarán con display:none). En cada pregunta habrá un enlace llamado ver respuesta, que al ser pulsado mostrará la respuesta de esa pregunta.

Update: solución del ejercicio

Bueno, no hay que desesperarse porque no salga. Hasta que se le coge el tranquillo a los selectores es normal atascarse. Dos formas de hacerlo.

Una es diciéndole que muestre el objeto span al pulsar en un objeto div que lo contiene. No es muy ortodoxa por razones que veremos más adelante.

  • ...
  • $.noConflict();
  • jQuery(document).ready(function($) {
  • // Ocultamos las respuestas
  • jQuery(".sinrespuesta").css("display", "none");
  • // Al hacer click en this (esta) .pregunta
  • jQuery(".pregunta", this).click(function () {
  • // mostramos el primer span
  • jQuery(".sinrespuesta", this).css("display", "block");
  • });
  • });
  • </script>
  • ...
  • <article id="cuestionario">
  • <p>Odiseo es...</p>
  • <div class="pregunta"><a href="#">Mostrar respuesta</a>
  • <span class="sinrespuesta">Un héroe griego</span>
  • </div>
  • <p>Quetzalcoatl es.</p>
  • <div class="pregunta"><a href="#">Mostrar respuesta</a>
  • <span class="sinrespuesta">Un dios mesoamericano</span>
  • </div>
  • <p>Odin es...</p>
  • <div class="pregunta"><a href="#">Mostrar respuesta</a>
  • <span class="sinrespuesta">Un dios vikingo</span>
  • </div>
  • </article>
  • ...

Otra, más elegante, es usando el selector jerárquico Child Selector.

  • <script type="text/javascript">
  • $.noConflict();
  • jQuery(document).ready(function($) {
  • // Ocultamos las respuestas
  • jQuery(".sinrespuesta").css("display", "none");
  • // Al hacer click en this (esta) .pregunta mostramos la respuesta
  • jQuery(".pregunta", this).click(function () {
  • jQuery(this > ".sinrespuesta").css("display", "block");
  • });
  • });
  • </script>

Bueno, en las próximas entradas profundizaremos más en los selectores.  🙂

Abrazos++;

←anterior - 5. Eventos básicos ||- En construcción

Notas

1. Con lo que hemos visto hasta ahora, no podríamos hacer un menú con tabuladores, ya veremos cómo se hace en próximas entradas, pero dejo aquí el código más parecido a los conceptos que he explicado hasta ahora. Lo siento, no se me ocurre cómo hacerlo más sencillo.

  • ...
  • $.noConflict();
  • jQuery(document).ready(function($) {
  • // inicializamos mostrando el primer tab y ocultamos el resto
  • jQuery(".tabuladores_desarrollo").hide();
  • jQuery(".tabuladores_desarrollo:first").show();
  • // tabulador activo en la barra de navegación
  • jQuery(".tabuladores_lista li", this).click(function() {
  • jQuery(".tabuladores_lista li").removeClass("tabuladores_item_activo");
  • jQuery(".tabuladores_lista li").addClass("tabuladores_item_inactivo");
  • jQuery(this).removeClass("tabuladores_item_inactivo");
  • jQuery(this).addClass("tabuladores_item_activo");
  • // mostramos el div
  • var detecta_div_a_activar = "tab"+(jQuery(this).index());
  • jQuery(".tabuladores_desarrollo").css("display","none");
  • jQuery("#"+detecta_div_a_activar).css("display","block");
  • });
  • });
  • </script>
  • </head>
  • <body>
  • <div class="tabuladores_contenedor">
  • <ul class="tabuladores_lista">
  • <li class="tabuladores_item_activo">Item 01</li>
  • <li class="tabuladores_item_inactivo">Item 02</li>
  • <li class="tabuladores_item_inactivo">Item 03</li>
  • </ul>
  • <div class="tabuladores_contenido">
  • <div id="tab0" class="tabuladores_desarrollo">Contenido Item 01</div>
  • <div id="tab1" class="tabuladores_desarrollo">Contenido Item 02</div>
  • <div id="tab2" Class="tabuladores_desarrollo">Contenido Item 03</div>
  • </div>
  • ...

|| Tags:

valoración de los lectores sobre jQuery Blues: 6.Selector contextual this

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración negativa
  • 4.1 sobre 5 (7 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

4 respuestas a “jQuery Blues: 6.Selector contextual this

  1. como colocar en el selector inputs serialisados
    <input type="text" name="modelo1"
    <input type="text" name="modelo2"
    <input type="text" name="modelo3"