jQuery: on, live, bind, click, …

En jQuery a la hora de asociar eventos a elementos del DOM surge la duda de cual utilizar. Por ejemplo si al boton

<button class="botonActivo">haz click</button>

queremos asociarle el evento click podriamos hacerlo de las siguientes maneras:

$('.botonActivo').click(function(){
  console.log( $(this).text() );
});

o bien

$('.botonActivo').on('click', function(){
  console.log( $(this).text() );
});

Va a dar exactamente igual cual uses. Ahora bien, jQuery desde su version 1.8 recomienda el uso de on() para asociar eventos  aunque sigue dando soporte para el “atajo” click.

Ahora vamos a clonar el boton e incluirlo en el DOM.

$('.botonActivo').on('click', function(){
  console.log( $(this).text() );
  $(this).clone().appendTo('body');
});

Si pulsamos sobre ese nuevo boton que ha aparecido no ocurrirá nada. No tiene ninguna acción asociada. En este caso, el de clonar, si queremos hacerlo para que contenga sus acciones asociadas a eventos tendremos que hacerlo pasándole true como parametro a clone().

$('.botonActivo').on('click', function(){
console.log( $(this).text() );
$(this).clone(true).appendTo('body');
});

El nuevo boton ahora clonaria otro mas.

 

Otra forma de hacer que los elementos que se incorporan al DOM una vez cargada la pagina tengan event handlers seria utilizando el metodo live().

$('.botonActivo').live('click', function(){
  console.log( $(this).text() );
  $(this).clone().appendTo('body');
});

Ahora no seria necesario incluir el parametro true a clone(). Ten en cuenta que el uso de live(), si no lo tenemos bien controlado, puede ser contraproducente.

Lo siguiente es ver el caso para deletegate(). Supongamos que tenemos el siguiente codigo HTML:

<div class="container">
  <button>boton</button>
  <button>boton</button>
</ul>

y el siguiente javascript:

$('.container').delegate('button','click',function(){
  $(this).clone().appentTo('body');
});

El nuevo boton no tendra asociado ningún event handler. Es así porque el appendTo() se realiza al body, si se realiza dentro del contexto del .container, si quedaría asociado a su tratamiento de eventos. Es decir, así:

$('.container').delegate('button','click',function(){
  $(this).clone().appentTo('.container');
});

Conviene saber que delegate en realidad utiliza live(), aunque dentro de un contexto determinado.

Si utilizamos bind(), que va cayendo en desuso, actualmente jQuery llama a on().

Ahora es cosa tuya decidir cual te conviene usar. Eso si, no conviene utilizar de forma indiscriminada live() para todo ya que consume  mas recursos que on(). Habría que estudiar bien la casuística.

Recuerda que a veces no hay que volverse loco y que seguimos pudiendo usar el tradicional onclick que llama a una function definida en javascript.

jQuery: on, live, bind, click, …

jQuery Mobile #4 – Botones

post anterior jQuery Mobile #3 Mostrar ventana de dialogo

Lo botones de jQuery Mobile son muy sencillos. Para incluir uno lo podemos hacer de una de las siguientes maneras:

  • mediante un enlace:  <a href=”#” class=”ui-btn”>boton link</a>
  • mediante el tag button: <button class=”ui-btn”>boton button</button>
  • mediante el tag input: <input type=”button” value=”boton input”>

jqm4-1

Vemos que los dos primero botones no tienen ni los bordes redondeados ni sombra paralela, solo el boton generado a traves de un input button. Para incluir los bordes redondeados y la sombra simplemente tendremos que incluir las clases “ui-corner-all” y “ui-shadow”

<a href="#" class="ui-btn ui-corner-all ui-shadow">boton link</a>
<button class="ui-btn ui-corner-all ui-shadow">boton button</button>
<input type="button" value="boton input">

jqm4-2

ver codigo

jQuery Mobile #4 – Botones

jQuery Mobile #1

Esta serie de jQuery Mobile pretende hacer un seguimiento a un proyecto que utiliza esta famosa libreria utilizada para proyecto de webapps o webs móviles.

Lo primero es ir a su web y descargarse la libreria. Yo he elegido la opción de “latest stable” (1.4.2) y la he metido tal cual en la tipica carpeta js/vendor.

Lo siguiente ha sido ir a boilerplate mobile y descargar la plantilla que los chicos de boilerplate nos sugieren para proyectos para móviles.

jQuery Mobile incluye todo lo necesario para crear webapps: navegación, framework CSS, y una buena colección de widgets. La idea es la de ir mas alla de simplemente utilizar las opciones por defecto.

De momento asi quedaria el index.html. En negrita se puede ver lo importante: las importaciones de los js y css y el contenido.

Dentro del contenido, para establecer una pagina le daremos al div que la contiene el atributo data-role=”page”

<!DOCTYPE html>
<!--[if IEMobile 7 ]> <html class="no-js iem7"> <![endif]-->
<!--[if (gt IEMobile 7)|!(IEMobile)]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Pagina Inicial - aitor_jqmobile</title>
<meta name="description" content="">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="cleartype" content="on">

<link rel="apple-touch-icon-precomposed" sizes="144x144" href="img/touch/apple-touch-icon-144x144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/touch/apple-touch-icon-114x114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="img/touch/apple-touch-icon-72x72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="img/touch/apple-touch-icon-57x57-precomposed.png">
<link rel="shortcut icon" href="img/touch/apple-touch-icon.png">

<!-- Tile icon for Win8 (144x144 + tile color) -->
<meta name="msapplication-TileImage" content="img/touch/apple-touch-icon-144x144-precomposed.png">
<meta name="msapplication-TileColor" content="#222222">
<!-- For iOS web apps. Delete if not needed. https://github.com/h5bp/mobile-boilerplate/issues/94 -->
<!--
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="">
-->

<!-- This script prevents links from opening in Mobile Safari. https://gist.github.com/1042026 -->
<!--
<script>(function(a,b,c){if(c in b&&b[c]){var d,e=a.location,f=/^(a|html)$/i;a.addEventListener("click",function(a){d=a.target;while(!f.test(d.nodeName))d=d.parentNode;"href"in d&&(d.href.indexOf("http")||~d.href.indexOf(e.host))&&(a.preventDefault(),e.href=d.href)},!1)}})(document,window.navigator,"standalone")</script>
-->

<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="js/vendor/jquery.mobile-1.4.2/jquery.mobile-1.4.2.min.css">
</head>
<body>
<div data-role="page">
<h1>Esta es la pagina inicial</h1>
<p>Probando, probando, ...</p>
</div>

<script src="js/vendor/jquery1.11.0.min.js"></script>
<script src="js/vendor/jquery.mobile-1.4.2/jquery.mobile-1.4.2.min.js"></script>
</body>
</html>
jQuery Mobile #1

Delegando Eventos (delegate)

A la hora de crear listeners de eventos podemos incurrir en ralentizar la pagina si el numero de estos es muy grande. Por ejemplo, si queremos realizar una acción por cada elemento de la una lista haríamos lo siguiente:

$('ul li').click(function() {

/* ... ... ... */

});

El codigo anterior genera un listener por cada elemento de la lista. Si la lista es muy grande tendremos el problema de ralentizar la pagina.

Podemos solucionarlo con la delegacion de eventos. En jQuery usaremos delegate()

$('ul').delegate('li', 'click', function(){

/* ... ... ... */

});

Otra ventaja de utilizar delegate() es que cualquier otro <li> que se incluya dinamicamente respondera tambien al evento.

Delegando Eventos (delegate)

Trabajando con la etiqueta select

Muchas veces cuando me toca trabajar con los combos y hay que determinar el valor seleccionado, el texto de la opción seleccionada, etc, me entran tal cantidad de dudas que siempre tengo que volver a buscarlo en Google. Así que he decido crear este post para tener siempre a mano la solución a esas dudas.

Para verlo funcionando puedes visitar el siguiente codepen: http://cdpn.io/izfgq (se utiliza jQuery)

Normalmente, las opciones que suelen necesitarse son:

  • Obtener el value del option seleccionado   $(‘#combo’).val()
  • Obtener el texto del option seleccionado   $(‘#combo option:selected’).text()
  • Establecer como seleccionado uno de los valores   $(‘#combo’).val(‘val-dos’)
  • Limpiar la combo   $(‘#combo’).html(”)
  • Cambiar las opciones del combo   $(‘#combo’).html(‘string con nuevas options’)
  • Incluir nuevas option    $(‘string con las option a incluir’).appendTo(‘#combo’)

Esto suele ser lo mas común. De todas formas, espero actualizar este post a medida que vaya necesitando nuevas funciones.

Trabajando con la etiqueta select