JQuery es una librería de abstracción del DOM con las siguientes funcionalidades y características:
La primera razón de utilizar JQuery, o librerías similares como prototype o YUI, es simple: compatibilidad. Los diferentes navegadores implementan de forma diferente el DOM a causa de la poca claridad con que están definidas algunas características del modelo en las especificaciones del W3C. También hay diferencias en la cantidad de funcionalidades implementadas. La librería se encarga de ocultar esas diferencias y evita la programación específica para cada familia de navegadores.
La segunda es que su sintaxis está diseñada para facilitar (y simplificar) la navegación por el documento, la selección de objetos del DOM, el manejo de eventos, la creación de animaciones y el desarrollo de aplicaciones Ajax.
Primero hemos de cargar las librerías en su versión comprimida (producción) o descomprimida (desarrollo), y lo podemos hacer de dos formas:
<script src="jquery-2.1.1.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Para poder acceder al DOM y manipular sus elementos hemos de asegurarnos que éstos se han cargado en su totalidad, para ello JQuery tiene el evento de documento ready:
$(document).ready(function() {
// Código a ejecutar
});
Podemos también verlo escrito de la siguiente forma:
$(function() {
// Código a ejecutar
});
Cuando el documento esté listo ejecuta el código. A diferencia del evento onload del DOM, el evento ready de JQuery no espera a que se carguen todas las imágenes e iframes de la página por lo que es mucho más rápido.
La sintaxis básica de JQuery es $(selector).accion()
, seleccionar elementos para hacer algo con ellos, donde:
Para poder manipular los elementos de una página web primero debemos seleccionarlos. JQuery utiliza selectores CSS para recuperar elementos del DOM.
Vamos a cargar el fichero html ejercicios-jquery.html en el navegador y abrimos la consola javascript.
El atributo id de un elemento del DOM debe ser único en la página.
$('#funcId')
$('.destacar')
$('p')
$('li')
$('ul:first')
$('ul:first li')
$('ul:first > li')
$('p:contains("DOM")')
$('*[id]')
$('a[target="_blank"]')
$('a[href*=".com"]')
Desde la pestaña Elements
seleccionar el tag li
con id="funcId"
y ocultarlo mediante el siguiente atributo de estilo display: none;
.
$('li:hidden')
Después de la primera selección podemos refinar el resultado o navegar por el árbol de DOM para acceder a elementos relacionados; en terminología JQuery traversing.
$('li').first()
$('li').last()
$('li').has('ul')
$('p').has('a')
$('p').eq(1)
$('#caracId').children()
$('#caracId').find('li')
$('#caracId').find('li').eq(1)
$('li:contains("32kb")').parent()
$('li:contains("32kb")').closest('li')
$('#funcId').find('li').eq(1).prev()
$('#funcId').find('li').eq(1).nextAll()
Ahora que sabemos seleccionar los elementos que necesitamos vamos a modificar la página cambiando las propiedades de los elementos o añadiendo/eliminando componentes del DOM.
$('a').hasClass('enlace')
$('a').addClass('enlace')
$('a').hasClass('enlace')
$('a').toggleClass('enlace')
$('#logo').width()
$('#logo').width(400)
$('p').eq(0).css('color', 'red')
$('p').eq(0).css({fontFamily: 'arial', fontSize: '18px'})
$('#caracId > ul').append('<li>Sencillo de aprender</li>')
$('span:contains(compa)').html('COMPATIBILIDAD')
$('h2').after('<p>Hay dos razones principales para utilizar JQuery:</p>')
JQuery facilita la gestión de eventos del navegador y de usuario.
$('img').click(function(){alert($(this).attr('src'))})
$('img').off('click')
$('li[id]').hover(function(){$(this).toggleClass('destacar')})
Proporciona una serie de funciones para añadir animaciones a las páginas web.
$('#logo').fadeOut()
$('#logo').fadeIn()
$('#logo').slideUp('slow')
$('#logo').slideDown()
$('#logo').slideDown('fast')
$('#logo').toggle() x 2
$('#logo').animate({width:'50%', marginLeft:'25%'}, 2000)
Para finalizar, JQuery dispone de un conjunto de funciones para realizar peticiones asíncronas a los servidores y modificar el contenido de la página sin necesidad de refrescarla (técnicas Ajax).
La función principal es $.ajax()
, que se encarga de realizar todas las peticiones Ajax de JQuery. Generalmente no se utiliza directamente ya que se definen funciones para peticiones específicas que simplifican muchísimo su uso:
$.get()
: petición get HTTP$.post()
: petición post HTTP$.getJSON()
: petición get de datos en formato JSON$.getScript()
: carga un script JavaScript y lo ejecuta$.load()
: carga html en un elementoRecuperamos el ejemplo del tema anterior. Utilizando JQuery el script con las funciones getWeather
y evalResp
quedaría de la siguiente manera:
function getWeather() {
var query= $('#ciudad').val();
if (query === '') {
alert('Texto en blanco');
return;
}
$.getJSON('http://api.openweathermap.org/data/2.5/find?type=like&lang=es&units=metric&q=' + query)
.done(function(data) {
var $div_resp= $('#div_resp');
if (data.cod !== '200' || data.count === 0) {
$div_resp.html('Ningún resultado');
} else {
$div_resp.empty();
for (var i= 0; i < data.list.length; i++) $div_resp.append('<b>'+data.list[i].name+' ('+data.list[i].sys.country+'):</b> '+data.list[i].main.temp+' ºC<br>');
}
})
.fail(function(jqxhr, textStatus, error) {
console.log('Error: ' + textStatus + ', ' + error );
});
}
Abrir ejemplo en el navegador...
Juego de cartas boca abajo donde hay que recordar la posición e ir haciendo parejas. En esta versión en lugar de imágenes se utilizan las tablas de multiplicar y se tienen como máximo 40 intentos para hacer las 10 parejas. Cada vez que se empieza un juego se selecciona aleatóriamente el valor del multiplicando entre 2 y 9.
La resolución del juego básicamente consiste en:
<body>
<div id="tablero">
<div id="titulo">Busca las parejas! Tienes hasta 40 clicks</div>
<div id="cartas"></div>
<div id="panel">
<span id="texto_panel">0 clicks</span>
<br><br>
<span class="boton"><a onclick="EmpezarJuego();">Repartir cartas</a></span>
</div>
</div>
</body>
* {
margin: 0;
padding: 0;
}
body {
font: 28px Verdana;
color: #fff;
background: #ddd;
}
#tablero {
margin: 20px auto;
width: 640px;
text-align: center;
}
#titulo {
text-align: center;
text-shadow: 1px 1px 2px black, 0 0 1em #4567e2, 0 0 0.2em #4567e2;
}
#cartas {
margin: 10px 0 0 10px;
}
#cartas div {
float: left;
width: 100px;
height: 100px;
line-height: 95px;
margin: 8px;
border: 4px solid #4567e2;
cursor: pointer;
border-radius: 10px;
box-shadow: 0 1px 5px rgba(0, 0, 0, .5);
background: #b1b1b1;
}
#cartas div span {
display: none;
font-weight: bolder;
vertical-align: middle;
line-height: normal;
}
#panel {
font: 18px Verdana;
color: #4567e2;
display: inline-block;
margin: 10px auto;
}
#panel .boton {
color: #fff;
background: #4567e2;
padding: 5px 10px;
margin: 5px;
border-radius: 10px;
cursor: pointer;
}
#panel .boton:hover {
color: #4567e2;
background: #fff;
border: 1px solid #4567e2;
}
Primero declaramos las variables necesarias para acceder a los elementos de la página y mantener el estado del juego, las declaramos globales para que sean visibles en todo el programa.
var $cartaArriba = null, // Guarda la primera carta de una pareja de clicks
$cartas = null, // Contenedor (div) de la lista de cartas
$texto_panel = null, // Mensajes de texto
numClicks = 0, // Contador de clicks
parejas = 0, // Contador de parejas
multiplicando = 0,
multiplicador = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
Buenas prácticas: es habitual con JQuery nombrar las variables que guardarán objetos JQuery con un
$
inicial, para distinguirlas de resto.
Luego, mediante $.ready
esperamos a que se haya cargado la página para iniciar la ejecución del programa. Recuperamos los elementtos HTML que cambiarán su contenido durante el juego (el div
de cartas y el panel de mensajes) y empezamos.
$(function () {
$cartas = $('#cartas');
$texto_panel = $('#texto_panel');
EmpezarJuego();
});
Cada vez que se empieza un juego debemos vaciar el contenedor de cartas, inicializar variables de estado y crear nuevas cartas.
function EmpezarJuego() {
// Elimina cartas
$cartas.empty();
// Resetear texto del panel
$texto_panel.html("0 clicks");
// Inicializa variables
numClicks = 0;
parejas = 0;
multiplicando = Math.floor(Math.random() * 8) + 2; // Número aleatorio entre 2 y 9
// Crea cartas
CrearCartas();
}
Para crear las cartas generamos primero en un array de 20 elementos, 10 strings con la operación de multiplicar y 10 con los resultados, y desordenamos dichos elementos.
Para cada elemento del array, creamos la carta: un contenedor div
con el texto.
Finalmente para cada contenedor le asignamos un evento click que ejecuta la función ClickCarta
.
function CrearCartas() {
var listaCartas = [];
// Crea la lista de multiplicaciones y resultados
for (var i = 0; i < 10; i++) {
listaCartas[i] = multiplicando + 'x' + multiplicador[i];
listaCartas[i + 10] = eval(multiplicando * multiplicador[i]);
}
// Mezcla las cartas
shuffle(listaCartas);
// Crea las cartas
for (i = 0; i < 20; i++) {
$cartas.append('<div id=carta' + i + '><span>' + listaCartas[i] + '</span></div>');
}
// Añade un manejador del evento click a cada carta
$cartas.children("div").click(ClickCarta);
}
No existe una función predefinida para mezclar el array, tenemos que escribir una. No reinventamos la rueda, buscamos algoritmos de ordenación y utilizamos la solución de Mike Bostock.
/* http://bost.ocks.org/mike/shuffle */
function shuffle(array) {
var m = array.length,
t, i;
// While there remain elements to shuffle
while (m) {
// Pick a remaining element
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}
Al hacer click a una carta, mediante $(this)
accedemos a la carta en cuestión (al contenedor div
).
Lo primero es impedir que se vuelva a hacer click en la misma carta, para ello eliminamos el evento; contabilizamos los clicks y actualizamos el panel de mensajes de texto; y visualizamos la carta.
Si es la primera carta de la pareja, la guardamos ($cartaArriba
) para compararla con la segunda en el próximo click. Si es la segunda, comprobamos si son iguales. Si lo son contabilizamos una pareja, si no las escondemos y les volvemos a asignar el evento click. Y empezamos ciclo de comparar parejas.
Finalmente comprobamos si hemos acabado el juego, o porque tenemos todas las parejas o porque hemos utilizado el número máximo de clicks.
function ClickCarta() {
var $carta = $(this),
$carta_span = $carta.find("span");
// No se puede hacer click en esta carta
$carta.off("click");
// Contabiliza clicks
numClicks++;
$texto_panel.html(numClicks + ' clicks');
// Visualiza la carta
$carta_span.fadeToggle();
// Primera carta
if ($cartaArriba === null) {
$cartaArriba = $carta;
} else { // Segunda carta
// Son iguales?
if (eval($carta_span.text().replace('x', '*') + ' == ' + $cartaArriba.find("span").text().replace('x', '*'))) { // Sí
parejas++;
} else { // Diferentes
$cartaArriba.find("span").delay(600).fadeToggle();
$carta_span.delay(600).fadeToggle();
// Habilitar el click nuevamente
$cartaArriba.click(ClickCarta);
$carta.click(ClickCarta);
}
$cartaArriba = null;
}
// Hemos terminado?
if (parejas == 10) { // Todas las parejas
$texto_panel.html('Has encontrado todas las parejas con ' + numClicks + ' clicks');
} else if (numClicks == 40) { // Número máximo de intentos
$texto_panel.html('Has llegado al máximo de intentos y sólo has conseguido ' + parejas + ' pareja' + (parejas > 1 ? 's' : ''));
// Quita el manejador del evento click a todas las cartas
$cartas.children("div").off("click");
}
}
Código fuente del proyecto aquí.