<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Facilitant la web &#187; Desenvolupament</title>
	<atom:link href="http://blog.facilitant.net/category/desenvolupament/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.facilitant.net</link>
	<description>Recursos, consells i reflexions sobre el món de la web</description>
	<lastBuildDate>Tue, 02 Mar 2010 11:10:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Validacions de formularis: a client o a servidor?</title>
		<link>http://blog.facilitant.net/2010/02/11/validacions-de-formularis-a-client-o-a-servidor/</link>
		<comments>http://blog.facilitant.net/2010/02/11/validacions-de-formularis-a-client-o-a-servidor/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 11:10:11 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Bones pràctiques]]></category>
		<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[accessibilitat]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[usabilitat]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=211</guid>
		<description><![CDATA[Els que ens dediquem a sistemes client-servidor, més específicament, a sistemes basats en web,  sovint ens trobem amb la necessitat de construir formularis que executin accions a partir d&#8217;una entrada. És ben normal, que un client o un funcional proclami:


Vull que el número d&#8217;identificació sigui obligatori!
El correu electrònic ha d&#8217;estar en el format correcte!


O altres [...]]]></description>
			<content:encoded><![CDATA[<p>Els que ens dediquem a sistemes client-servidor, més específicament, a sistemes basats en web,  sovint ens trobem amb la necessitat de construir formularis que executin accions a partir d&#8217;una entrada. És ben normal, que un client o un funcional proclami:</p>
<blockquote>
<ul>
<li>Vull que el número d&#8217;identificació sigui obligatori!</li>
<li>El correu electrònic ha d&#8217;estar en el format correcte!</li>
</ul>
</blockquote>
<p>O altres típics requeriments que requereixin de fer una validació del formulari.</p>
<p>Davant d&#8217;aquest escenari, el primer que ens ve al cap és fer les validacions amb JavaScript a la capa client. Bé, no està malament. Fer les validacions a la capa de client, és ràpid en temps de computació, senzill (normalment) i proporciona una resposta ràpida a l&#8217;usuari, fet pel qual assegurem una bona experiència d&#8217;usuari mentre introduïm dades. Una de les primeres normes de la usabilitat a formularis és: com més aviat sàpiga l&#8217;usuari que s&#8217;ha equivocat, més aviat podrà reaccionar-hi (compte amb la interpretació d&#8217;aquesta frase <dfn title="De collita pròpia">made-by-me</dfn>!). Però mai hem d&#8217;acabar aquí!</p>
<p>Fer les validacions <strong>només</strong> a la capa client és una decisió completament errònia. On de debò s&#8217;han de fer aquestes comprovacions és a la capa servidor. Allà és on s&#8217;ha de mirar si cert camp existeix, si el format de tal camp és el correcte, de si la relació entre dos camps és correcta, etc. És a la capa servidor on tot aquest algorisme s&#8217;ha d&#8217;executar per prevenir qualsevol error que pugui tenir l&#8217;aplicació. És allà on s&#8217;executa la lògica de l&#8217;aplicació i on les validacions, com part d&#8217;aquesta lògica que són, s&#8217;han d&#8217;executar. Si només ho féssim a client, què passaria si no tinguéssim disponible el JavaScript? Quin seria el comportament de l&#8217;aplicació? Possiblement, acabéssim en un estat d&#8217;inconsistència no desitjat per ningú.</p>
<p>Sovint quan es planteja aquest argument (validacions dobles a capa client i servidor), molts <em>arquitectes </em>d&#8217;aplicacions (remarco la paraula perquè és el títol que es posen ells, no el que els hi posaria jo) posen el crit al cel i diuen la del porc argumentant que s&#8217;està fent una tasca dues vegades i que el rendiment de l&#8217;aplicació en general es veu ressentit. Si alguna vegada us trobeu davant d&#8217;això, només heu de dir:</p>
<blockquote><p>D&#8217;acord, llavors, les validacions que es facin només a la capa de servidor!</p></blockquote>
<p>Veureu com els hi canvia la cara <img src='http://blog.facilitant.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Cal tenir ben presents quines són les implicacions de deixar un processament de dades a una capa tan fràgil com pot ser un navegador, i la nostra tasca és argumentar i deixar ben clar el per què a client no és lloc per fer aquest tipus de processament.</p>
<p>Tingueu aquest consell sempre ben present perquè segur que al llarg de la vostra vida professional us caldrà utilitzar-lo més d&#8217;un cop.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2010/02/11/validacions-de-formularis-a-client-o-a-servidor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comprovacions de l&#8217;existència d&#8217;una variable a JavaScript</title>
		<link>http://blog.facilitant.net/2009/12/21/comprovacions-de-lexistencia-duna-variable-a-javascript/</link>
		<comments>http://blog.facilitant.net/2009/12/21/comprovacions-de-lexistencia-duna-variable-a-javascript/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 12:45:38 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=194</guid>
		<description><![CDATA[Quan programem amb JavaScript (o qualsevol altre llenguatge de scripting) és normal haver de fer comprovacions de l&#8217;existència d&#8217;una variable dins de l&#8217;espai de noms.
Si necessitem saber si una variable ha estat declarada però sense valor assignat, podem comparar-la amb el &#8220;valor&#8221; undefined. Així podem veure:
var x;
// x === undefined retornaria cert
x = 5;
// x [...]]]></description>
			<content:encoded><![CDATA[<p>Quan programem amb JavaScript (o qualsevol altre llenguatge de scripting) és normal haver de fer comprovacions de l&#8217;existència d&#8217;una variable dins de l&#8217;espai de noms.</p>
<p>Si necessitem saber si una variable ha estat declarada però sense valor assignat, podem comparar-la amb el &#8220;valor&#8221; <code class="javascript">undefined</code>. Així podem veure:</p>
<pre><code class="javascript">var x;
// x === undefined retornaria cert
x = 5;
// x === undefined retornaria fals</code></pre>
<p>Però si el que de debò volem fer és comprovar si aquesta variable ha estat definida en algun punt del script, no podem fer aquesta comprovació, ja que al intentar cercar el símbol &#8220;x&#8221; a la seva taula de noms, ens donaria un error de referència. Llavors, podem fer-ho o no? La resposta és sí! Només cal comprovar el seu tipus: si no té un tipus definit, vol dir que no està definida dins la taula de noms. Total, que podem fer:</p>
<pre><code class="javascript">// typeof(y) === undefined retornaria cert
var y;
// typeof(y) === undefined retornaria fals</code></pre>
<p>I ja per acabar amb nota: com fer per saber si certa variable està definida directament en l&#8217;àmbit global de l&#8217;script? Doncs bé, com bé sabem, qualsevol variable definida a l&#8217;espai global, està també definida com un camp de l&#8217;objecte global. Llavors, els que ens dediquem a la programació web, i per tant tenim l&#8217;objecte <code class="javascript">window</code> com a objecte global, podem fer la comprovació:</p>
<pre><code class="javascript">window.z === undefined
// retornaria cert si la variable z no ha estat definida</code></pre>
<p>Doncs res, aquest ha estat el truc del dia. Espero que us sigui útil!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/12/21/comprovacions-de-lexistencia-duna-variable-a-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Protegir pàgines amb l&#8217;event onbeforeunload</title>
		<link>http://blog.facilitant.net/2009/09/09/protegir-pagines-amb-levent-onbeforeunload/</link>
		<comments>http://blog.facilitant.net/2009/09/09/protegir-pagines-amb-levent-onbeforeunload/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 14:30:43 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[usabilitat]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=173</guid>
		<description><![CDATA[No us ha passat mai que mentre esteu acabant d&#8217;omplir un formulari, sense adonar-vos, feu clic allà on no toca i perdeu tot el que heu introduït? Doncs bé, hi ha una senzilla manera per evitar al màxim aquests errors: l&#8217;event onbeforeunload.
Cap allà als mitjans dels noranta, Internet Explorer 4.0 introduí aquest event no estàndard, [...]]]></description>
			<content:encoded><![CDATA[<p>No us ha passat mai que mentre esteu acabant d&#8217;omplir un formulari, sense adonar-vos, feu clic allà on no toca i perdeu tot el que heu introduït? Doncs bé, hi ha una senzilla manera per evitar al màxim aquests errors: l&#8217;event <code class="javascript">onbeforeunload</code>.</p>
<p>Cap allà als mitjans dels noranta, Internet Explorer 4.0 introduí aquest event no estàndard, però a diferència d&#8217;altres ocasions, aquest cop feu una cosa útil i els navegadors amb motor Gecko ho acabaren introduint a la versió 1.7 de Mozilla (Firefox 1.0).</p>
<p>Aquest event, tal i com resa el seu nom, es dispara just <strong>abans</strong> de l&#8217;event <code class="javascript">onunload</code>, és a dir, abans que es descarregui el contingut actual de la pàgina, i per tant, ens permet executar algun tipus d&#8217;acció en aquest moment.</p>
<p>A diferència dels altres events, aquest funciona força diferent: per tal de mostrar un missatge a l&#8217;usuari abans de descarregar la pàgina, el que cal fer és retornar una cadena amb el missatge que es vulgui mostrar. Un exemple podria ser:</p>
<pre><code class="javascript">
window.onbeforeunload = function(e) {
  return "No heu enviat el formulari. Si tanqueu la pàgina perdreu tots els canvis fets fins ara.";
}
</code></pre>
<p>Així, en cas d&#8217;abandonar la pàgina, se&#8217;ns mostraria un quadre amb el missatge:</p>
<blockquote><p>Esteu segur que voleu sortir d’aquesta pàgina?</p>
<p><em>No heu enviat el formulari. Si tanqueu la pàgina perdreu tots els canvis fets fins ara.</em></p>
<p>Premeu D’acord per a continuar, o cancel·la per a romandre a la pàgina actual</p></blockquote>
<p>Les frases que hi ha just abans i després de les nostres les posa el navegador (en aquest cas Firefox) i no es poden eliminar, substituir ni evitar de cap tipus de les maneres.</p>
<p>Val a dir que en cas que el navegador no tingui implementat aquest event, aquests simplement l&#8217;ignoraran i no mostraran pas el missatge a l&#8217;usuari.</p>
<h3>Pàgines protegides</h3>
<p>Recapitulem. La raó principal d&#8217;aquest article és que fa poc a la feina em varen demanar que implementés una funcionalitat per a protegir pàgines: volien poder mostrar un missatge quan un usuari intentés abandonar la pàgina enmig d&#8217;un formulari dins d&#8217;un procés amb un cert flux o bé intentés abandonar una pàgina, la construcció de la qual fos molt costosa. Un exemple ideal per a treure l&#8217;event <code class="javascript">onbeforeunload</code> de la nostra cartera de recursos. Anem a construir-ho.</p>
<p>Per tal de poder marcar si una pàgina la tractem com a protegida o no, és a dir, si registrem l&#8217;event <code class="javascript">onbeforeunload</code> per mostrar un missatge a l&#8217;usuari en cas d&#8217;abandonar la pàgina, afegirem la classe <code>protected</code> a l&#8217;element <code class="html">/body</code> de la pàgina:</p>
<pre><code class="html">&lt;body class="protected"&gt;</code></pre>
<p>Així, si usem jQuery, podem afegir les següents línies de codi per a tenir-ho fet:</p>
<pre><code class="javascript">$('body.protected').each(function () {
  window.onbeforeunload = function(e){
    return "Si abandones, ho perdràs tot per sempre!";
  };
});
</code></pre>
<p>Però tenim un petit inconvenient: si fem clic en un enllaç o si enviem el formulari fent clic a un botó, se&#8217;ns mostrarà el missatge, cosa que volem evitar. Això es pot resoldre inhabilitant l&#8217;event en cas de fer clic a certs elements:</p>
<pre><code class="javascript">$('body.protected p.botons input, body.protected a.sense-onbeforeunload', context).click(function () {
  window.onbeforeunload = null;
});</code></pre>
<p>I així de fàcil obtenim el que busquem. Fàcil, oi? I segur que a més d&#8217;un li sembla útil, i fins i tot, més que necessari en alguna situació quotidiana.</p>
<h3>Recursos</h3>
<ul>
<li><a lang="en" xml:lang="en" hreflang="en" href="http://msdn.microsoft.com/en-us/library/ms536907%28VS.85%29.aspx">Onbeforeunload event. Internet Explorer Developer Center</a></li>
<li><a lang="en" xml:lang="en" hreflang="en" href="https://developer.mozilla.org/en/DOM/window.onbeforeunload">Window.onbeforeunload. Mozilla Developer Center</a></li>
<li><a lang="es" xml:lang="es" hreflang="es" href="http://blog.scriptia.net/articulos/2007/01/onbeforeunload.html">onbeforeunload: tiende una mano al usuario</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/09/09/protegir-pagines-amb-levent-onbeforeunload/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Com fer un plugin per a jQuery. Contingut tabulat en pestanyes</title>
		<link>http://blog.facilitant.net/2009/07/22/com-fer-un-plugin-per-a-jquery-contingut-tabulat-en-pestanyes/</link>
		<comments>http://blog.facilitant.net/2009/07/22/com-fer-un-plugin-per-a-jquery-contingut-tabulat-en-pestanyes/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 18:53:16 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=148</guid>
		<description><![CDATA[Durant el meu dia a dia professional, treballo (i força) amb jQuery, una meravellosa biblioteca JavaScript (s’entreveuen les meves preferències, oi?). Doncs bé, la segona cosa que cal saber quan s’entra en el món jQuery és desenvolupar, o com a mínim conèixer l&#8217;estructura bàsica, d&#8217;un plugin.
Per a exemplificar la construcció, crearem un petit giny per [...]]]></description>
			<content:encoded><![CDATA[<p>Durant el meu dia a dia professional, treballo (i força) amb jQuery, una meravellosa biblioteca JavaScript (s’entreveuen les meves preferències, oi?). Doncs bé, la segona cosa que cal saber quan s’entra en el món jQuery és desenvolupar, o com a mínim conèixer l&#8217;estructura bàsica, d&#8217;un plugin.</p>
<p>Per a exemplificar la construcció, crearem un petit giny per a construir contingut tabulat en pestanyes.</p>
<p>Partim d’un fragment HTML com el següent:</p>
<pre><code class="html">&lt;div class="pestanyes"&gt;
  &lt;h2&gt;Pestanya 1&lt;/h2&gt;
  &lt;div&gt;
    ...contingut...
  &lt;/div&gt;
  &lt;h2&gt;Pestanya 2&lt;/h2&gt;
  &lt;div&gt;
    ...contingut de la segona...
  &lt;/div&gt;
  &lt;h2&gt;Pestanya 3&lt;/h2&gt;
  &lt;div&gt;
    ...i una mica més...
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
<p>Si ens centrem en el giny, podríem redactar una petita explicació funcional com la següent:</p>
<ul>
<li>En estat de repòs, es mostren les pestanyes amb la primera activa i només es mostra el contingut relacionat amb aquesta.</li>
<li>Una vegada cliquem a una pestanya, aquesta passa a ser l’activa i el contingut que es mostra passa a ser el relacionat amb aquesta.</li>
</ul>
<p>Ara només falta traduir això a codi JavaScript.</p>
<p>Comencem creant l&#8217;estructura general del plugin:</p>
<pre><code class="javascript">$('.pestanyes').each(function() {
  ...
});</code></pre>
<p>I les estructures necessàries per a crear el giny. Primer de tot caldrà amagar les capçaleres i el contingut d&#8217;aquestes i crear l&#8217;estructura per a les pestanyes que a nosaltres ens sigui còmode de treballar-hi. Per exemple una d&#8217;ideal seria una senzilla llista <code class="html">&lt;ul&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;</code>.</p>
<p>Anem a passar tot això a codi JavaScript:</p>
<pre><code class="javascript">$('div.pestanyes').each(function () {
  // creem una referència a les capçaleres i al contingut de les pestanyes
  var $headings = $('h2', this);
  var $content = $headings.next();

  // amaguem les capçaleres i els continguts
  $headings.hide();
  $content.hide();

  // creem l'estructura de les pestanyes
  var tabHtml = '';
  $headings.each(function() {
    tabHtml += '&lt;li&gt;' + $(this).text() + '&lt;\/li&gt;';
  });

  // i l'afegim al document
  $(this).prepend('&lt;ul class="tabs"&gt;' + tabHtml + '&lt;\/ul&gt;');
}</code></pre>
<p>Una vegada creada l&#8217;estructura, només queda marcar l&#8217;estat inicial amb la primera pestanya i el seu contingut relacionat com a actius:</p>
<pre><code class="javascript">var $tabs = $('ul.tabs li');
$tabs.eq(0).addClass('active');
$content.eq(0).show();</code></pre>
<p>Ara només ens queda centrar-nos en la interacció amb les pestanyes. Quan un usuari faci clic en una pestanya, cal resetejar l&#8217;estat actual (eliminar la marca d&#8217;actiu) i marcar la pestanya que s&#8217;ha clicat com a activa, juntament amb el seu contingut relacionat.</p>
<pre><code class="javascript">$tabs.click(function() {
  // eliminem la classe i amaguem el contingut
  $tabs.removeClass('active');
  $content.hide();

  // marquem la pestanya activa i mostrem el contingut que calgui
  $(this).addClass('active');
  var tabIndex = $tabs.index(this);
  $content.eq(tabIndex).show();
});</code></pre>
<p>Si ho posem tot junt, podem veure el resultat i una aplicació a un cas a l&#8217;<a href="http://blog.facilitant.net/exemples/plugin-jquery/pestanyes.html">exemple</a>.</p>
<p>Però fins aquí no hem fet res de res per construir un plugin. Posem-nos a treballar-hi.</p>
<h3>Adaptació del codi per a ser un plugin vàlid</h3>
<p>Quan pensem en crear un plugin jQuery, el que ens ve al cap és crear una funcionalitat reutilitzable dins del domini d&#8217;un objecte jQuery, és a dir, estendre l&#8217;objecte. Així, si ens centrem en el nostre exemple, la idea és acabar creant un codi tal que per poder crear un contingut tabulat, hàgim d&#8217;escriure simplement:</p>
<pre><code class="javascript">$('div.pestanyes').tabs();</code></pre>
<p>Si el que volem és estendre l&#8217;objecte jQuery el que haurem de fer, igual que en qualsevol altre objecte JavaScript, és afegir  una nova propietat al seu objecte <code class="javascript">prototype</code>. Així, una cosa d&#8217;aquest tipus seria vàlid:</p>
<pre><code class="javascript">$.prototype.tabs = function () {
  // el nostre codi
}</code></pre>
<p>Però si hagués decidit fer-ho així, ja s&#8217;hauria acabat l&#8217;entrada, i aquesta no és pas la idea.</p>
<p>Si mirem les primeres línies de la biblioteca jQuery, podem veure la creació d&#8217;un alies força interessant:</p>
<pre><code class="javascript">jQuery.fn = jQuery.prototype</code></pre>
<p>Així, si volem usar aquesta notació, podem ampliar directament l&#8217;objecte tot fent:</p>
<pre><code class="javascript">$.fn.tabs = function () {
  // el meu codi
  return this;
}</code></pre>
<p>S&#8217;ha afegit el retorn del propi objecte per a poder permetre l&#8217;encadenament de crides:</p>
<pre><code class="javascript">$('#element')
  .tabs()
  .mesCoses();</code></pre>
<p>El plugin que estem construint és força senzill, però què passaria si tinguéssim variables globals, funcions auxiliars i demés? Alguna cosa com aquesta:</p>
<pre><code class="javascript">var foo = 0;
$.fn.myPlugin = function () {
  foo += 5;
  myMethod();
  return this;
}
function myMethod() {
  ...
}</code></pre>
<p>Amb aquest escenari, algú sense gaires llums (o amb ganes de tocar la pera) podria usar el plugin des la següent forma (i des de l&#8217;espai global de noms):</p>
<pre><code class="javascript">var myMethod = 'bar';
$('#element').myPlugin();
</code></pre>
<p>Però per sort, nosaltres tenim un as sota la màniga anomenat <span lang="en" xml:lang="en">closure. Així, podem englobar <strong>tot</strong> el codi del nostre plugin dins d&#8217;una funció anònima:</span></p>
<pre><code class="javascript">(function () {
  var foo = 0;
  $.fn.myPlugin = function () {
    foo += 5;
    myMethod();
    return this;
  }
  function myMethod() {
    ...
  }
}) ();</code></pre>
<p>Sembla que tot ja està fet, no? Queda un últim punt. Per a assegurar la compatibilitat amb d&#8217;altres biblioteques, no podem usar l&#8217;àlies de l&#8217;objecte jQuery <code class="javascript">$</code> així com així, sinó que hauríem d&#8217;usar <code class="javascript">jQuery</code> com a mètode d&#8217;accés a l&#8217;objecte. Però això no és gaire còmode, no? Tranquils! Aprofitant que tenim la funció anònima englobant el nostre codi, podem crear un àlies segur per a <code class="javascript">jQuery</code> fàcilment passant-lo com a paràmetre d&#8217;aquesta:</p>
<pre><code class="javascript">(function($) {
  ...
})(jQuery);</code></pre>
<p>Ara ja estem en condicions de crear el nostre primer plugin. Podeu veure el codi resultant a l&#8217;<a href="http://blog.facilitant.net/exemples/plugin-jquery/pestanyes-plugin.html">exemple</a>.</p>
<h3>Ampliacions</h3>
<p>Una vegada que tenim el plugin funcionant, ens podem centrar en fer-lo més real. El primer que ens podem preguntar és: què és un plugin sense opcions? Doncs si en volem, només cal donar-li un parell de voltes i fet.</p>
<p>Considerem dues opcions de configuració:</p>
<ul>
<li>Pestanya activada per defecte, que serà un enter (per defecte 0) que indicarà l&#8217;index de la pestanya (<code class="javascript">activatedIndex</code>)</li>
<li>Efecte visual al canviar de pestanya, que serà el nom d&#8217;una funció (per defecte null) dins l&#8217;espai de noms de l&#8217;objecte jQuery (<code class="javascript">animation</code>)</li>
</ul>
<p>I si ho afegim al codi que ja tenim:</p>
<pre><code class="javascript">$.fn.tabs = function (options) {
  var config = $.extend({
    activatedIndex: 0,
    animation: null
  }, options || {});

  ...
}</code></pre>
<p>Ara el mètode <code class="javascript">tabs</code> accepta un paràmetre que és un objecte de configuració. S&#8217;usa el mètode <code class="javascript">$.extend</code> per tal d&#8217;estendre un objecte amb els valors per defecte amb els passats com a paràmetre.</p>
<p>Ara, els únics canvis que cal fer són força trivials. Pel cas de l&#8217;índex de la pestanya a activar:</p>
<pre><code class="javascript">// marquem la pestanya i el contingut desat a la configuració com actiu
var $tabs = $('ul.tabs li');
$tabs.eq(config.activatedIndex).addClass('active');
$content.eq(config.activatedIndex).show();
</code></pre>
<p>I pel cas de l&#8217;animació al canviar de pestanya:</p>
<pre><code class="javascript">if(config.animation) {
  $content.eq(tabIndex)[config.animation]();
} else {
  $content.eq(tabIndex).show();
}</code></pre>
<p>I per acabar, només falta veure-ho tot ajuntat i funcionant al seu <a href="http://blog.facilitant.net/exemples/plugin-jquery/pestanyes-plugin-2.html">exemple</a> corresponent.</p>
<h3>Fonts</h3>
<p>No creieu pas que sóc un geni. Ni molt menys. Aquesta entrada està basada en <a hreflang="es" href="http://blog.scriptia.net/articulos/2008/10/jquery-del-espagueti-al-plugin.html">una</a> de molt millor del meu amic <a hreflang="es" href="http://choangalvez.nom.es/">Choan</a>, el qual em va iniciar en el meravellós món del JavaScript. Només he volgut explicar-ho des de la meva òptica, usant alguna que altra alternativa de notació i amb un exemple ben diferent.</p>
<div class="nota">
<p>Cal deixar ben clar que això no és pas un plugin oficial ni res per l&#8217;estil. El codi el teniu disponible per tocar i jugar, però no s&#8217;acceptaran cap tipus de culpa per l&#8217;ús d&#8217;aquest en algun entorn productiu.</p>
<p>El que sí que s&#8217;accepten són notes, comentaris i tot el que vulgueu fer sobre el que aquí s&#8217;ha exposat.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/07/22/com-fer-un-plugin-per-a-jquery-contingut-tabulat-en-pestanyes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Separar la forma del contingut (nom de les classes)</title>
		<link>http://blog.facilitant.net/2009/06/29/separar-la-forma-del-contingut-nom-de-les-classes/</link>
		<comments>http://blog.facilitant.net/2009/06/29/separar-la-forma-del-contingut-nom-de-les-classes/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 09:01:03 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Bones pràctiques]]></category>
		<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=136</guid>
		<description><![CDATA[Es ben sabut per tots els que ens dediquem a la programació d&#8217;interfícies web (també anomenats maquetadors o programadors front end) que cal tenir ben present que sempre s&#8217;ha de separar el document (HTML) de la seva presentació en un medi concret (CSS) i dels components amb comportament que pugui tenir (JavaScript). Així, és fàcil [...]]]></description>
			<content:encoded><![CDATA[<p>Es ben sabut per tots els que ens dediquem a la programació d&#8217;interfícies web (també anomenats maquetadors o programadors <span lang="en" xml:lang="en">front end</span>) que cal tenir ben present que sempre s&#8217;ha de separar el document (<acronym title="Hypertext Markup Language" xml:lang="en">HTML</acronym>) de la seva presentació en un medi concret (<acronym title="Cascading Style Sheets" xml:lang="en">CSS</acronym>) i dels components amb comportament que pugui tenir (JavaScript). Així, és fàcil veure que el següent fragment d&#8217;un document és completament incorrecte pel que fa a aquests cànons:</p>
<pre><code class="html">
&lt;div style="margin: 5px;"&gt;
    &lt;em&gt;Aquest contingut el vull en lletra cursiva&lt;/em&gt;
    &lt;small&gt;&lt;a onclick="window.location='/lipsum'" href="http://www.example.com"&gt;Lorem ipsum dolor&lt;/a&gt;&lt;/small&gt;
&lt;/div&gt;
</code></pre>
<p>Normalment la majoria de programadors som ben conscients de la incorrecció del fragment anterior, però sovint ens trobem incorreccions d&#8217;aquest tipus completament encobertes, i sempre seguint el mateix patró: el mal ús dels noms de classe dels elements.</p>
<p>Usaré exemples de la xarxa per a il·lustrar el que vull dir. Si anem a la portada de la pàgina d&#8217;una institució molt important del país podem trobar coses així (canvio els texts per centrar l&#8217;atenció):</p>
<pre><code class="html">
&lt;ul id="ul_home"&gt;
	&lt;li&gt;&lt;a class="vermell_nobullet_2" href="http://www.example.com"&gt;Ipse quat erimo&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a class="vermell_nobullet_2" href="http://www.example.com/dog"&gt;Sailer due rit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<pre><code class="html">
&lt;div class="marge_superior"&gt;
    &lt;h2&gt;&lt;span id="actualitat" class="titol_seccio"&gt;Lorem ipsum&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;div id="altres_serveis" class="border_top"&gt;
    &lt;div class="border_bottom"&gt;
        &lt;a class="text_gris" href="http://www.example.com/bird"&gt;Dolor et sumum&lt;/a&gt;
    &lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p>El valor de l&#8217;atribut <code class="html">@class</code> d&#8217;alguns dels elements ja ens dóna informació de com s&#8217;estilitzaran al veure-ho associat al seu full d&#8217;estils.</p>
<p>Però sovint no es veu tan fàcilment la incorrecció a l&#8217;assignació dels noms de les classes. Per exemple, és ben normal trobar-nos sempre al fragment de descripció de  l&#8217;organització d&#8217;un document, classes del tipus:</p>
<pre><code class="html">
&lt;body class="3-columnes"&gt;
    &lt;div class="columna-esquerra"&gt;
        Lorem ipsum
    &lt;/div&gt;
    &lt;div class="columna-central"&gt;
        Dolor set
    &lt;/div&gt;
    &lt;div class="columna-dreta"&gt;
        Icse et luopir
    &lt;/div&gt;
&lt;/body&gt;
</code></pre>
<p>Hi veieu res d&#8217;estrany? Per saber si les classes són reveladores de la forma final, només cal que us feu la següent pregunta: podríeu saber quina és la forma final de la pàgina només llegint l&#8217;<acronym title="Hypertext Markup Language" xml:lang="en">HTML</acronym>? Si la resposta és sí, les classes són errònies. Si és no, doncs la cosa ja està millor.</p>
<p>Per exemple, una forma correcte de fer la divisió del document podria ser:</p>
<pre><code class="html">
&lt;body class="layout-complet"&gt;
    &lt;div class="contingut-primari"&gt;
        Lorem ipsum
    &lt;/div&gt;
    &lt;div class="contingut-secundari"&gt;
        Dolor set
    &lt;/div&gt;
    &lt;div class="contingut-terciari"&gt;
        Icse et luopir
    &lt;/div&gt;
&lt;/body&gt;
</code></pre>
<p>Oi que ara ja no us espereu com serà el document final?</p>
<p>Per tant, cal anar amb compte a l&#8217;hora d&#8217;assignar els noms a les classes. Sempre cal tenir ben present de separar la forma o presentació del contingut i anar una mica amb peus de plom a l&#8217;hora de cercar els valors. Així aconseguirem que els nostres documents siguin 100% independents de la forma en que es visualitzen.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/06/29/separar-la-forma-del-contingut-nom-de-les-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problemes amb l&#8217;append de jQuery a Internet Explorer</title>
		<link>http://blog.facilitant.net/2009/05/25/problemes-amb-lappend-de-jquery-a-internet-explorer/</link>
		<comments>http://blog.facilitant.net/2009/05/25/problemes-amb-lappend-de-jquery-a-internet-explorer/#comments</comments>
		<pubDate>Mon, 25 May 2009 11:00:44 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=130</guid>
		<description><![CDATA[De tots és ben conegut que ser el més popular de la classe no vol dir pas que siguis el més bo, ni el més educat, i encara menys, el més efectiu. Doncs això és principalment el que li passa a l&#8217;Internet Explorer.
Si treballem amb JavaScript d&#8217;una forma intensiva és normal usar alguna biblioteca que [...]]]></description>
			<content:encoded><![CDATA[<p>De tots és ben conegut que ser el més popular de la classe no vol dir pas que siguis el més bo, ni el més educat, i encara menys, el més efectiu. Doncs això és principalment el que li passa a l&#8217;<span lang="en" xml:lang="en">Internet Explorer</span>.</p>
<p>Si treballem amb <span lang="en" xml:lang="en">JavaScript</span> d&#8217;una forma intensiva és normal usar alguna biblioteca que ens ajudi en algunes tasques del dia a dia d&#8217;interacció amb <abbr title="Document Object Model" lang="en" xml:lang="en">DOM</abbr>, events i demés; i una de les biblioteques més populars actualment és <a lang="en" xml:lang="en" hreflang="en" href="http://jquery.com/">jQuery</a> (que és també la que uso jo normalment als meus projectes).</p>
<p>El cas que ens ocupa és una de les funcions de principals de manipulació del <abbr title="Document Object Model" lang="en" xml:lang="en">DOM</abbr>: <a href="http://docs.jquery.com/Manipulation/append" lang="en" xml:lang="en" hreflang="en">append</a>. Imaginem-nos que tenim un codi semblant a aquest:</p>
<pre><code class="javascript">$('div.el-que-interessa').append('&lt;span class="foo"&gt;');</code></pre>
<p>Doncs bé, des de <span lang="en" xml:lang="en">Firefox</span>, per exemple, l&#8217;element <code class="html">/span</code> sí que serà afegit, però en canvi a <span lang="en" xml:lang="en">Internet Explorer</span> no ho serà pas. Aquest darrer requereix que el fragment que es vulgui afegir mitjançant aquesta funció sigui <acronym title="eXtensible Hypertext Markup Language" lang="en" xml:lang="en">XHTML</acronym>. Així hauria de quedar una cosa com aquesta:</p>
<pre><code class="javascript">$('div.el-que-interessa').append('&lt;span class="foo"&gt;&lt;\/span&gt;');</code></pre>
<p>No sembla pas una cosa gaire complexa de detectar i solucionar, oi? Doncs donem-li una volta més de rosca&#8230;</p>
<p>Imaginem-nos que volem afegir opcions a una llista desplegable de forma dinàmica, i tenim un codi com el següent:</p>
<pre><code class="javascript">$.each(opcions, function(clau, valor) {
    $llista.append(new Option(valor, clau));
});</code></pre>
<p>És correcte o no és correcte aquest codi? Per saber-ho, hauríem de modificar la pregunta i fer-la més o menys així: quin <acronym title="Hypertext Markup Language" lang="en" xml:lang="en">HTML</acronym> ens retorna el constructor de la classe Option?</p>
<pre><code class="javascript">var opt = new Option('Catalunya', 'CT');
// opt: &lt;option value="CT"&gt;Catalunya</code></pre>
<p>Doncs bé, com podeu veure, el codi retornat per l&#8217;objecte no és pas en format <acronym title="eXtensible Hypertext Markup Language" lang="en" xml:lang="en">XHTML</acronym>, i per tant, no funcionarà a <span lang="en" xml:lang="en">Internet Explorer</span>. Per aconseguir el correcte funcionament, no tenim cap més opció que inserir l&#8217;opció en format text:</p>
<pre><code class="javascript">$.each(opcions, function(clau, valor) {
    $llista.append('&lt;option value="' + clau + '"&gt;' + valor + '&lt;\/option&gt;');
});</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/05/25/problemes-amb-lappend-de-jquery-a-internet-explorer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Amagar sense ocultar amb CSS</title>
		<link>http://blog.facilitant.net/2009/05/12/amagar-sense-ocultar-amb-css/</link>
		<comments>http://blog.facilitant.net/2009/05/12/amagar-sense-ocultar-amb-css/#comments</comments>
		<pubDate>Tue, 12 May 2009 18:48:39 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Bones pràctiques]]></category>
		<category><![CDATA[accessibilitat]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=126</guid>
		<description><![CDATA[Sovint ens interessa amagar contingut de la nostra pàgina a l&#8217;ull humà com pot ser el cas dels menús per a saltar a continguts de la pàgina, en l&#8217;ús de tècniques de reemplaçament de contingut per imatges o per ocultar capçaleres o elements estructurals de la pàgina. És veritat que ens interessa amagar-ho de l&#8217;ull [...]]]></description>
			<content:encoded><![CDATA[<p>Sovint ens interessa amagar contingut de la nostra pàgina a l&#8217;ull humà com pot ser el cas dels menús per a saltar a continguts de la pàgina, en l&#8217;ús de tècniques de reemplaçament de contingut per imatges o per ocultar capçaleres o elements estructurals de la pàgina. És veritat que ens interessa amagar-ho de l&#8217;ull humà, però el que no volem de cap de les maneres, és amagar-ho dels lectors de pantalla.</p>
<h3>El típic error</h3>
<p>Si donem una volta per la xarxa, el que sovint trobem escrit i recomanat, és l&#8217;ús de la propietat <code class="css">display: none</code> per a ocultar elements. Amb això satisfem la nostra voluntat de que l&#8217;ull humà no percebi el contingut, però el problema és que sovint, els lectors de pantalla tampoc n&#8217;interpreten res.</p>
<p>Podríem dir que <code class="css">display: none</code> significa que l&#8217;element no existeix: ni es mostra, ni s&#8217;imprimeix, ni es llegeix el seu contingut.</p>
<h3>La solució</h3>
<p>Una tècnica alternativa que es pot considerar és la de posicionar l&#8217;element que volem amagar de forma absoluta fora del <span lang="en" xml:lang="en">viewport</span>. Així, l&#8217;element existeix però no es percep per l&#8217;ull humà. El <acronym title="Cascading Style Sheet" lang="en" xml:lang="en">CSS</acronym> que podem usar és:</p>
<pre><code class="css">.access {
    left: -9999px;
    position: absolute;
}</code></pre>
<p>Amb això aconseguim el mateix efecte visual però sense ignorar a una part dels usuaris.</p>
<p>Tot això no és pas invenció meva, sinó que és una adaptació d&#8217;<a hreflang="en" href="http://www.456bereastreet.com/archive/200905/hiding_with_css_problems_and_solutions/">un article</a> que vaig llegir fa uns dies.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/05/12/amagar-sense-ocultar-amb-css/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Arguments a favor i en contra de l&#8217;ús d&#8217;iframes</title>
		<link>http://blog.facilitant.net/2009/03/31/arguments-a-favor-i-en-contra-de-lus-diframes/</link>
		<comments>http://blog.facilitant.net/2009/03/31/arguments-a-favor-i-en-contra-de-lus-diframes/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 16:27:33 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Bones pràctiques]]></category>
		<category><![CDATA[Reflexions]]></category>
		<category><![CDATA[accessibilitat]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[iframe]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=113</guid>
		<description><![CDATA[Per temes de feina avui he hagut de fer un llistat d&#8217;arguments a favor i en contra de l&#8217;ús d&#8217;iframe en un desenvolupament web i m&#8217;he decidit a fer-la pública perquè tothom que vulgui pugui opinar-ne.
A favor

Integració d&#8217;aplicacions. Permet integrar aplicacions externes a dins de la nostra pàgina.
Disminució de peticions a servidor. Si tenim una [...]]]></description>
			<content:encoded><![CDATA[<p>Per temes de feina avui he hagut de fer un llistat d&#8217;arguments a favor i en contra de l&#8217;ús d&#8217;<code class="html">iframe</code> en un desenvolupament web i m&#8217;he decidit a fer-la pública perquè tothom que vulgui pugui opinar-ne.</p>
<h3>A favor</h3>
<ul>
<li><strong>Integració d&#8217;aplicacions.</strong> Permet integrar aplicacions externes a dins de la nostra pàgina.</li>
<li><strong>Disminució de peticions a servidor</strong>. Si tenim una part de la nostra pàgina que és costosa de construir (dins d&#8217;un entorn de pagines dinàmiques), podem posar-la dins d&#8217;un <code class="html">/iframe</code> fent que no s&#8217;hagi de refrescar cada cop que canviem de pàgina (seguint una mica el model del ja deprecat element <code class="html">/frame</code>).</li>
</ul>
<h3>En contra</h3>
<ul>
<li><strong>Forat negre.</strong> Al poder-hi posar tot el que vulguem, un <code class="html">/iframe</code> pot arribar a ser un problema de seguretat si no som nosaltres els creadors del seu contingut.</li>
<li><strong>Accessibilitat.</strong> Existeixen navegadors que no suporten l&#8217;ús de l&#8217;element <code class="html">iframe</code>.</li>
<li><strong>Lectors de pantalla. </strong>Hi ha navegadors que per defecte donen el focus al <code class="html">iframe</code> en el moment de carregar la pàgina. Això és un problema per a la correcta lectura del document pels lectors de pantalla.</li>
<li><strong>Cercadors. </strong>Les aranyes dels cercadors no saben navegar correctament per les pàgines que usen marcs. Per tant, pot ser que el nostre lloc no sigui correctament indexat.</li>
<li><strong>Estructura del contingut.</strong> L&#8217;ús de l&#8217;element <code class="html">iframe</code> trenca l&#8217;estructura lògica del contingut de la pàgina.</li>
<li><strong>Gran confusió al interactuar amb el navegador.</strong> Diverses interaccions de l&#8217;usuari amb el navegador es veuen greument modificades per l&#8217;ús de l&#8217;element <code class="html">iframe</code> en una pàgina:
<ul>
<li><strong>URL.</strong> La URL que es veu al navegador no és sovint la que correspon a la d&#8217;una pàgina creada amb marcs: si anem navegant dins del marc, la URL del navegador no canvia, però en canvi, la de la pàgina que estem veient sí que &#8220;ha canviat&#8221;.</li>
<li><strong>Adreces d&#8217;interès.</strong> Lligat amb el punt anterior, si volem desar l&#8217;adreça de la plana, la que desarem serà la que es veu al navegador. Al tornar-hi veurem  que no és pas la mateixa plana que havíem desat (haurem perdut la navegació dins del marc). Tot i que hi ha navegadors que ens donen la possibilitat d&#8217;esbrinar l&#8217;adreça d&#8217;un marc, pot ser que l&#8217;usuari sigui no especialitzat i per tant, no sàpiga de l&#8217;existència d&#8217;aquesta possibilitat. Igualment, un usuari de la plana no ha de saber com està feta la pàgina, i per tant, saber com ha de fer-s&#8217;ho per desar l&#8217;enllaç  &#8220;correcte&#8221; a la plana en qüestió.</li>
<li><strong>Resultats d&#8217;una cerca.</strong> Si accedim a una pàgina feta amb marcs des d&#8217;un resultat d&#8217;un cercador extern, pot dur-nos a una adreça  &#8220;incorrecte&#8221;: podem anara a l&#8217;adreça d&#8217;un marc, on veurem el contingut d&#8217;aquest però sense el contingut del seu &#8220;pare&#8221;.</li>
</ul>
</li>
<li><strong>Alçada fixa.</strong> Un <code class="html">iframe</code> té alçada fixa, i per tant, pot ser que ens aparegui una barra de desplaçament lateral en cas que el contingut ocupi més espai del reservat per l&#8217;atribut <code class="html">@height</code> del marc.</li>
</ul>
<h3>Alternatives</h3>
<p>En cas que usem marcs només per temes estètics no tenim excusa per abandonar-los, ja que el seu aspecte es pot replicar 100% amb <acronym title="Cascading Style Sheets" xml:lang="en">CSS</acronym>.</p>
<p>Si usem marcs per tal de poder deixar una part de la nostra pàgina fixa mentre fem <span lang="en" xml:lang="en">scroll</span> de la pàgina, podem usar la propietat <code class="css">position: fixed</code> de <acronym title="Cascading Style Sheets" xml:lang="en">CSS</acronym> tal i com s&#8217;explica en aquest <a hreflang="en" href="http://www.w3.org/Style/Examples/007/menus.html">article</a>.</p>
<p>En canvi, si el que volem és que cert contingut de la pàgina tingui una barra lateral per poder navegar dins seu, podem usar la propietat <code class="css">overflow</code> tal i com s&#8217;explica en aquest altre <a hreflang="en" href="http://www.quirksmode.org/css/overflow.html">article</a>.</p>
<h3>Conclusions</h3>
<p>A data d&#8217;avui, i a no ser que sigui algun motiu de rendiment o d&#8217;integració, l&#8217;ús de marcs no està justificat en un inici, ja que provoca més desavantatges que no pas avantatges. Sovint la necessitat d&#8217;aquest element recau més per un tema gràfic que no pas per un tema funcional, cosa que com ja hem vist, es pot resoldre amb l&#8217;ús de fulls d&#8217;estils.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/03/31/arguments-a-favor-i-en-contra-de-lus-diframes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ús de selectors CSS atípics: els selectors d&#8217;atribut</title>
		<link>http://blog.facilitant.net/2009/02/05/us-de-selectors-css-atipics-els-selectors-datribut/</link>
		<comments>http://blog.facilitant.net/2009/02/05/us-de-selectors-css-atipics-els-selectors-datribut/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 15:21:55 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[selectors]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=93</guid>
		<description><![CDATA[Quan parlem de selectors CSS sovint ens venen al cap o als ulls expressions d&#8217;aquest tipus:
* {...}
e {...}
e f {...}
e &#62; f {...}
e, f {...}
Però dins l&#8217;àmbit de selectors, hi ha tot un món de possibilitats que ens poden ajudar molt al nostre dia a dia (sinó, doneu-li un cop d&#8217;ull a l&#8217;apartat de selectors [...]]]></description>
			<content:encoded><![CDATA[<p>Quan parlem de selectors <acronym xml:lang="en" title="Cascading Style Sheets">CSS</acronym> sovint ens venen al cap o als ulls expressions d&#8217;aquest tipus:</p>
<pre><code class="css">* {...}
e {...}
e f {...}
e &gt; f {...}
e, f {...}</code></pre>
<p>Però dins l&#8217;àmbit de selectors, hi ha tot un món de possibilitats que ens poden ajudar molt al nostre dia a dia (sinó, doneu-li un cop d&#8217;ull a l&#8217;apartat de selectors de l&#8217;especificació de <a href="http://www.w3.org/TR/CSS2/selector.html" hreflang="en"><acronym xml:lang="en" title="Cascading Style Sheets">CSS</acronym>2<sup>1</sup></a> o de <a href="http://www.w3.org/TR/css3-selectors/" hreflang="en"><acronym xml:lang="en" title="Cascading Style Sheets">CSS</acronym>3</a>).</p>
<p>Del gran conjunt de selectors, en aquesta entrada vull parlar una mica i posar diversos exemples de com treure-li profit als selectors d&#8217;atribut. Abans de continuar, i per variar una mica, aquest tipus de selectors no funcionen en Internet Explorer 6 o anterior.</p>
<p>Els selectors d&#8217;atribut són els següents:</p>
<table border="0">
<thead>
<tr>
<th>Patró</th>
<th>Significat</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="css">E[foo]</code></td>
<td>Un element E amb un atribut &#8220;foo&#8221;</td>
</tr>
<tr>
<td><code class="css">E[foo="bar"]</code></td>
<td>Un element E amb un atribut &#8220;foo&#8221; i el seu valor és exactament &#8220;bar&#8221;</td>
</tr>
<tr>
<td><code class="css">E[foo~="bar"]</code></td>
<td>Un element E amb un atribut &#8220;foo&#8221; que és una llista de valors separats per espais i un d&#8217;aquests és &#8220;bar&#8221;</td>
</tr>
<tr>
<td><code class="css">E[foo^="bar"]</code></td>
<td>Un element E amb un atribut &#8220;foo&#8221; i el seu valor comença exactament per &#8220;bar&#8221;</td>
</tr>
<tr>
<td><code class="css">E[foo$="bar"]</code></td>
<td>Un element E amb un atribut &#8220;foo&#8221; i el seu valor acaba exactament per &#8220;bar&#8221;</td>
</tr>
<tr>
<td><code class="css">E[foo*="bar"]</code></td>
<td>Un element E amb un atribut &#8220;foo&#8221; i el seu valor conté la cadena &#8220;bar&#8221;</td>
</tr>
<tr>
<td><code class="css">E[foo|="bar"]</code></td>
<td>un element E amb un atribut &#8220;foo&#8221; que és una llista de valors separats per guions i comença per &#8220;bar&#8221;</td>
</tr>
</tbody>
</table>
<p>Per exemplificar l&#8217;ús d&#8217;aquest tipus de selectors, prendrem com a cas d&#8217;ús la personalització d&#8217;enllaços en diferents situacions.</p>
<p>Per exemple, i tal i com es fa en aquest bloc amb els enllaços, podríem voler adjuntar de forma visible pel lector quin és l&#8217;idioma de la pàgina enllaçada. Aquí ho fem amb la següent regla:</p>
<pre><code class="css">a[hreflang]:after {
  content: " ["attr(hreflang)"]";
  font-size: 0.8em;
}</code></pre>
<p>Seguint l&#8217;exemple dels idiomes, podríem voler marcar l&#8217;enllaç d&#8217;un cert idioma amb una icona gràfica al seu voltant. Per exemple, en el cas del català, ho podríem fer de la següent manera:</p>
<pre><code class="css">a[hreflang="ca"] {
  background: url(icona-catala.png) no-repeat right center;
  padding-right: 1em;
}</code></pre>
<p>Seguint amb aquests exemples, imaginem-nos que tenim un enllaç on el seu atribut <code class="html">rel</code> té el conjunt de valors <code>friend met co-worker muse</code> i volem caracteritzar els amics amb una icona especial al costat de l&#8217;enllaç. Doncs bé, ho podríem fer amb el següent codi:</p>
<pre><code class="css">a[rel~="friend"] {
  background: url(icona-amic.png) no-repeat right center;
  padding-right: 1em;
}</code></pre>
<p>Si ens interessés destacar amb alguna icona, tots els enllaços que tinguessin com a destí el <abbr title="World Wide Web Consortium" xml:lang="en">W3C</abbr>, podríem fer servir el següent codi:</p>
<pre><code class="css">a[href^="http://www.w3c.org"] {
  background: url(icona-w3c.png) no-repeat right center;
  padding-right: 1em;
}</code></pre>
<p>O per exemple, si volguéssim posar-li una icona del format del fitxers enllaçat, podríem usar el següent codi pel cas del <acronym title="Portable Document Format" xml:lang="en">PDF</acronym>:</p>
<pre><code class="css">a[href$=".pdf"] {
  background: url(icona-pdf.png) no-repeat right center;
  padding-right: 1em;
}</code></pre>
<p>Seguint amb tot això, si volem tenir un enllaç caracteritzat si el seu atribut <code class="html">title</code> o l&#8217;<code class="html">href</code> conté la paraula &#8220;css&#8221;, podem usar el següent codi:</p>
<pre><code class="css">a[title*="css"][href*="css"]:after {
  color: #000;
  content: " (enllaç sobre CSS)";
  font-size: 0.8em;
}</code></pre>
<p>I per acabar amb el darrer selector i tornant amb els exemples de la caracterització d&#8217;enllaços segons el seu idioma, podríem voler caracteritzar tots els enllaços en anglès amb una icona, independentment de si és anglès americà (<code>en-US</code>) o el general (<code>en</code>):</p>
<pre><code class="css">a[hreflang|="en"] {
  background: url(icona-angles.png) no-repeat right center;
  padding-right: 1em;
}</code></pre>
<p>Amb tots aquests exemples, es pot veure que gràcies a aquest selector, se&#8217;ns obra tot un món de possibilitats a l&#8217;hora de caracteritzar diversos elements.</p>
<div class="nota">
Com a curiositat, fa un temps, quan encara no havia sortit Internet Explorer 7 i degut a que les versions anteriors no reconeixien aquest selector, els maquetadors més radicals usaven aquest selector per a tenir dues versions diferents d&#8217;un lloc: una per a Internet Explorer i l&#8217;altre per als demés navegadors. Això ho podien aconseguir fent regles d&#8217;aquest estil:</p>
<pre><code class="css">
div#contenidor {
  /* estils per a IE6 i anteriors */
}

div[id="contenidor"} {
  /* estils per als altres navegadors */
}
</code></pre>
<p>No digueu que no és curiós, oi?</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/02/05/us-de-selectors-css-atipics-els-selectors-datribut/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Àmbit d&#8217;una variable a javascript</title>
		<link>http://blog.facilitant.net/2009/01/13/ambit-duna-variables-a-javascript/</link>
		<comments>http://blog.facilitant.net/2009/01/13/ambit-duna-variables-a-javascript/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 16:12:25 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Bones pràctiques]]></category>
		<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=74</guid>
		<description><![CDATA[L&#8217;àmbit d&#8217;una variable es pot definir com l&#8217;àrea del programa en que aquesta és visible i accessible.
Com a la majoria de llenguatges de programació, en javascript pots declarar una variable com a global, definida en tot l&#8217;àmbit del codi javascript, o com a local, definida només dins de l&#8217;àmbit de la funció que la defineix.
var [...]]]></description>
			<content:encoded><![CDATA[<p>L&#8217;àmbit d&#8217;una variable es pot definir com l&#8217;àrea del programa en que aquesta és visible i accessible.</p>
<p>Com a la majoria de llenguatges de programació, en javascript pots declarar una variable com a global, definida en tot l&#8217;àmbit del codi javascript, o com a local, definida només dins de l&#8217;àmbit de la funció que la defineix.</p>
<pre><code class="javascript">var a = 0;        // variable global
function foo() {
  var b = 1;      // variable local
}
</code></pre>
<p>Cal tenir sempre en compte que una variable local sempre té precedència davant d&#8217;una variable global, és a dir, si una paràmetre d&#8217;una funció o una variable declarada dins del seu àmbit té el mateix nom que una variable global, aquesta darrera queda <em>oculta</em> per la nova declaració.</p>
<pre><code class="javascript">var ambit = 'global';    // Declarem una variable global
function foo() {
  var ambit = 'local';   // Declarem una variable local
  document.write(ambit); // Usem la variable local
}
foo();                   // Imprimeix 'local'
</code></pre>
<p>Fins aquí tot força senzill, no? Però si us fixeu, encara no he dit res sobre la paraula reservada <code class="javascript">var</code>.</p>
<p>Javascript ens deixa usar variables sense haver-les de definir amb la paraula <code class="javascript">var</code>, però què passa si no ho fem? Doncs bé, si l&#8217;interpretador troba que s&#8217;està assignant un valor en una variable que no està declarada, la declara com a global i llavors li assigna el valor. Llavors cal tenir en compte que sempre que vulguem declarar una variable local, hem d&#8217;usar <code class="javascript">var</code>.</p>
<pre><code class="javascript">ambit = 'global';              // Declarem una variable global (sense var)
function foo() {
  ambit = 'local';             // Ostres! Hem canviat el valor de la variable global!
  document.write(ambit);       // Usa la variable global
  nou_ambit = 'local';         // Declarem una nova variable global
  document.write(nou_ambit);   // Usa la nova variable global
}
foo();                         // Imprimeix 'locallocal'
document.write(ambit);         // Imprimeix 'local' (el valor s'ha canviat dins la funció)
document.write(nou_ambit);     // Imprimeix 'local' (la variable s'ha creat a la funció però amb àmbit global)</code></pre>
<p>En general, una funció no sap quines variables estan definides en l&#8217;àmbit global i quines no. Així, si una funció usa una variable global en comptes d&#8217;una local sense saber-ho, pot estar modificant un valor que pot afectar a d&#8217;altres parts del programa. Per sort, la solució a tota aquesta problemàtica és ben senzilla: declareu sempre totes les variables amb <code class="javascript">var</code>.</p>
<p>Però si seguim estirant del fil, podem trobar altres coses curioses relacionades amb l&#8217;àmbit de variables.</p>
<p>A diferència d&#8217;altres llenguatges de programació, javascript no defineix l&#8217;àmbit d&#8217;una variable a nivell de bloc (només existeixen àmbits a nivell global o local!). Així, totes les variables declarades dins d&#8217;una funció, sigui on sigui, estan definides a nivell de tota la funció. Si mirem el següent codi podrem entendre-ho:</p>
<pre><code class="javascript">function foo(a) {
  var i = 0;                       // i està definida a tota la funció
  if (a == 5) {
    var j = 23;                    // j està definida a tota la funció, no només en aquest bloc
    for(var k = 0; k &lt; 20; k++) {  // k està definida a tota la funció, no només en aquest bucle
      document.write(k);
    }
    document.write(k);             // k està definida, i té valor 20
  }
  document.write(j);               // j està definida però pot ser que no estigui inicialitzada
}</code></pre>
<p>Cal tenir en compte que el fet que una variable declarada dins d&#8217;una funció està definida per tota la funció pot donar-nos alguna que altra sorpresa. Per exemple:</p>
<pre><code class="javascript">var ambit = 'global';
function foo() {
  alert(ambit);          // Mostra 'undefined', no pas 'global'
  var ambit = 'local';   // Variable inicialitzada aquí, però definida en tot l'àmbit de la funció
  alert(ambit);          // Mostra 'local'
}
foo();
</code></pre>
<p>Pot semblar-nos que el primer cop que es crida a la funció <code class="javascript">alert()</code> hauria de mostrar-nos &#8220;global&#8221; ja que la declaració de la variable local encara no s&#8217;ha executat. Però si tenim en compte les regles d&#8217;àmbit que he anat explicant, la variable local està definida en tot l&#8217;àmbit de la funció, ocultant la variable global que du el mateix nom. Però igualment, encara que la variable local està definida, aquesta no està inicialitzada fins que no s&#8217;executa la sentència <code class="javascript">var</code>. Així, la funció <code class="javascript">foo()</code> anterior és equivalent a la següent:</p>
<pre><code class="javascript">var ambit = 'global';
function foo() {
  var ambit;             // La variable local es defineix a l'inici de la funció
  alert(ambit);          // En aquest punt existeix, però té valor 'undefined'
  var ambit = 'local';   // En aquest punt la inicialitzem i li donem un valor
  alert(ambit);          // Aquí ja té valor!
}
</code></pre>
<p>Amb aquest exemple il·lustra perfectament el perquè és una bona pràctica el declarar totes les variables a l&#8217;inici de cada funció.</p>
<div class="nota">Tots els exemples que s&#8217;usen en aquesta entrada estan basats en els que es poden trobar al del llibre <cite>Javascript: The Definitive Guide</cite></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/01/13/ambit-duna-variables-a-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
