<?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>Pensamento Web</title>
	<atom:link href="http://www.caugb.com.br/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.caugb.com.br</link>
	<description>Textos sobre desenvolvimento web</description>
	<lastBuildDate>Sat, 08 May 2010 18:50:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>jQuery.scrollIntoView</title>
		<link>http://www.caugb.com.br/2010/05/jquery-scrollintoview/</link>
		<comments>http://www.caugb.com.br/2010/05/jquery-scrollintoview/#comments</comments>
		<pubDate>Sat, 08 May 2010 18:42:07 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[jquery plugin]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://www.caugb.com.br/?p=117</guid>
		<description><![CDATA[Este plugin se propõe a ser um substituto ao método nativo scrollIntoView. A idéia é fazer o mesmo &#8211; rolar a página até que o elemento que evocou o método esteja visível &#8211; mas de forma suave &#8211; rolando a &#8230; <a href="http://www.caugb.com.br/2010/05/jquery-scrollintoview/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
dt { margin-top:20px; font-weight:bold; font-size:1.1em; } 
dd pre { font-size:1.05em; } 
</style>
<p>Este plugin se propõe a ser um substituto ao método nativo <code>scrollIntoView</code>. A idéia é fazer o mesmo &#8211; rolar a página até que o elemento que evocou o método esteja visível &#8211; mas de forma suave &#8211; rolando a página, literalmente. Diferentemente do método nativo, esse script irá alinhar o elemento (primeiro do set de elementos encontrados) no  centro da janela por padrão. Uma desvantagem é que não podemos alinhar em baixo como o método nativo permite, mas há algumas vantagens adicionais. Aqui podemos centralizar o elemento na página ou em cima, definir o tempo de rolagem e executar uma função callback opcional ao final da rolagem.<br />
<span id="more-117"></span></p>
<dl>
<dt>$(&#8216;.target&#8217;).scrollIntoView()</dt>
<dd>vai executar a rolagem segundo o objeto de configuração padrão (veja abaixo)</dd>
<dt>$(&#8216;.target&#8217;).scrollIntoView( duration, [ callback ] )</dt>
<dd>vai executar a rolagem para o centro em <code>duration</code> milisegundos, executando a função <code>callback</code> (opcional) ao final da rolagem</dd>
<dt>$(&#8216;.target&#8217;).scrollIntoView( options )</dt>
<dd>options é um objeto contendo itens de configuração suportados (veja abaixo)</dd>
<dt>O objeto de configuração e seus valores padrão</dt>
<dd> var options = {<br />
&#8216;duration&#8217;: 1000,   // duração da rolagem (milisegundos)<br />
&#8216;forceTop&#8217;: false,  // true para alinhar no topo<br />
&#8216;forceLeft&#8217;: false, // true para alinhar à esquerda<br />
&#8216;marginTop&#8217;: 10,    // margem para alinhamento no topo<br />
&#8216;marginLeft&#8217;: 10,   // margem para alinhamento à esquerda<br />
&#8216;complete&#8217;: null,   // função para ser executada no final da rolagem (use <code>this</code> para se referir ao elemento DOM)<br />
&#8216;easing&#8217;: &#8216;swing&#8217;   // efeito usado em <code>.animate()</code> (linear|swing)<br />
}; </dd>
<dt>Exemplos de uso</dt>
<dd><a href="/scripts/scrollintoview/anchor-replacing.html" class="html external blank"  target="_blank">Substituindo âncoras (links para a mesma página)</a><br />
<a href="/scripts/scrollintoview/siv-test.html" class="html external blank"  target="_blank">Rolagem vertical e horizontal</a></dd>
</dl>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2010/05/jquery-scrollintoview/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Remover o BOM de arquivos em UTF-8</title>
		<link>http://www.caugb.com.br/2009/07/remover-o-bom-de-arquivos-em-utf-8/</link>
		<comments>http://www.caugb.com.br/2009/07/remover-o-bom-de-arquivos-em-utf-8/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 01:47:39 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
				<category><![CDATA[Funções]]></category>
		<category><![CDATA[bom]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://www.caugb.com.br/?p=102</guid>
		<description><![CDATA[BOM &#8211; Byte Order Mark &#8211; é um identificador para arquivos em UTF-8/16/32 (vou ignorar o 16 e o 32 aqui), teoricamente para dizer ao interpretador/editor que se trata de um conteúdo codificado como UTF-8, mas o fato é que, &#8230; <a href="http://www.caugb.com.br/2009/07/remover-o-bom-de-arquivos-em-utf-8/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>BOM &#8211; <a href="http://en.wikipedia.org/wiki/Byte-order_mark" class="http external blank"  target="_blank">Byte Order Mark</a> &#8211; é um identificador para arquivos em UTF-8/16/32 (vou ignorar o 16 e o 32 aqui), teoricamente para dizer ao interpretador/editor que se trata de um conteúdo codificado como UTF-8, mas o fato é que, em quase todas as circunstâncias, ele é dispensável.</p>
<p>Caso o seu interpretador não reconheça a codificação, você poderá ver algo como &#8220;<strong>ï»¿</strong>&#8221; no início de arquivos em utf8 &#8211; na verdade antes do início do arquivo, o que faz com que esse código só seja visível em caso de erro &#8211; normalmente ele só será visível num editor hexadecimal.<span id="more-102"></span></p>
<p>Mas qual é o problema? O  meu problema foi em PHP, usando include para adicionar um conteúdo em UTF-8. A questão é que, se tivermos incluído um arquivo em UTF-8 (com o BOM) antes de usar funções como header(), veremos aquele conhecido erro que diz que uma função que manipula os cabeçalhos HTTP (header e outras) não pôde ser executada porque a saída já havia iniciado, portanto os cabeçalhos já haviam sido enviados. Mas você não mandou imprimir nada!</p>
<p>Bem, aí temos que lembrar que o PHP não é um interpretador de arquivos de texto, portanto o BOM no início do arquivo é apenas algo que está fora do escopo da TAG <code>&lt;?php ... ?&gt;</code>. Se temos um arquivo assim:</p>
<pre lang="php">&lt;?php $something = 'anything'; ?&gt;
&lt;?php print_to_file($something); ?&gt;</pre>
<p>Esse arquivo não imprime nada, certo? Errado, ele imprime (implicitamente) uma quebra de linha que está entre <code>?&gt;</code> e <code>&lt;?php</code> &#8211; porque tudo o que estiver fora do escopo das tags PHP é HTML, que é enviado imediatamente para o browser. Isso é o mesmo que imprimir com <code>print</code> ou <code>echo</code> ou outra. Ok, então corrigi o arquivo e agora ele está assim:</p>
<pre lang="php">&lt;?php $something = 'anything';
print_to_file($something); ?&gt;</pre>
<p>Perfeito. Então salvo em UTF-8 e&#8230; erro! por que? veja como ficou o arquivo para o PHP:</p>
<pre lang="php">ï»¿&lt;?php $something = 'anything';
print_to_file($something); ?&gt;</pre>
<p>A solução é remover o BOM e, provavelmente, isso não fará a menor diferença &#8211; pra mim não fez nenhuma. Mas como remover o BOM? Pensei, se dá pra ver num editor hexadecimal, dá pra deletar&#8230; baixei e instalei o <a href="http://www.pspad.com" class="http com external blank"  target="_blank">PsPad</a> (um editor excelente para programadores) mas não pude remover o danado, não dá (ou eu não soube).<br />
Bem, achei um script em Perl que fazia isso e com base nele, fiz um em PHP que funcionou perfeitamente aqui. Pode ser que seja útil para você.</p>
<pre lang="php">&lt;?php
// substitua pelo caminho para o arquivo que deseja limpar
$file = "C:/wamp/www/wordpress/wp-content/themes/basic-gray/lib/langs.php";
print removeUTF8BOM($file) ? 'BOM removido!' : 'Não havia BOM a ser removido...';

function removeUTF8BOM($fil) {
$newcontent = '';
$first = false;
$fh = fopen($fil, 'r');
  while($part = fread($fh, 1024)) {
    if(!$first) {
      if(preg_match('/^\xEF\xBB\xBF/', $part)) {
      $newcontent = preg_replace('/^\xEF\xBB\xBF/', "", $part);
      } else {
      fclose($fh);
      return false;
      }
    $first = true;
    } else $newcontent .= $part;
  }
fclose($fh);
$fh = fopen($fil, 'w');
fwrite($fh, $newcontent);
fclose($fh);
return true;
}
?&gt;</pre>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2009/07/remover-o-bom-de-arquivos-em-utf-8/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Konami Code em sites web, mas pra quê?</title>
		<link>http://www.caugb.com.br/2009/06/konami-code-em-sites-web/</link>
		<comments>http://www.caugb.com.br/2009/06/konami-code-em-sites-web/#comments</comments>
		<pubDate>Sat, 13 Jun 2009 03:35:48 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[konami]]></category>

		<guid isPermaLink="false">http://www.caugb.com.br/?p=90</guid>
		<description><![CDATA[Quando descobri o Konami Code Sites e vi que sites como Digg, jQuery, FaceBook e muitos outros haviam aderido àquela brincadeira, comecei a navegar pelos sites e ver o que cada um aprontava ao executarmos o Konami Code. Bem divertido! &#8230; <a href="http://www.caugb.com.br/2009/06/konami-code-em-sites-web/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Quando descobri o <a href="http://konamicodesites.com/" class="http external blank"  target="_blank">Konami Code Sites</a> e vi que sites como Digg, jQuery, FaceBook e muitos outros haviam aderido àquela brincadeira, comecei a navegar pelos sites e ver o que cada um aprontava ao executarmos o <a href="http://pt.wikipedia.org/wiki/Konami_code" class="http external blank"  target="_blank">Konami Code</a>.<br />
Bem divertido! Logo pensei: vou fazer um desses pra mim&#8230;</p>
<p>Achei então um script da família Google, o <a href="http://konami-js.googlecode.com/svn/trunk/konami.js" class="http js external self" >konami.js</a>, que oferece suporte também para iPhone e adiciona um [Enter] no fim do famoso código antes de executar a função (como em alguns games). Mas qual seria a graça em usar um script pronto? (nenhuma, claro! <img src='http://www.caugb.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) O caso é que escrevi o meu próprio script&#8230; Não tem contagem de tempo entre as teclas digitadas, apenas identifica a sequência correta e chama a função konamiFunction, se existir. Funciona direitinho.</p>
<p>Maneiro! Aí fui comentar (empolgado) com meu amigo <a href="http://www.gugaalves.net/" class="http external blank"  target="_blank">Guga</a> e ele perguntou: legal, mas pra que serve isso? A pergunta pegou na veia. &#8220;Não sei, pra brincar&#8230;&#8221;, respondi. E fiquei pensando naquilo &#8211; que ainda não tinha passado pela minha cabeça&#8230;<span id="more-90"></span></p>
<p>Claro, serve para brincar com o seu visitante. É, mas é mais que isso. Navegando descobri que o Konami Code é um verdadeiro símbolo para uma geração (ou mais) de aficcionados em games. Natualmente, descobrir que o site que você visita tem alguma surpresa para quem digita o código que funcionava nos games que você jogava é um fator de identificação forte com esse usuário. E tenha certeza: esse é um <em>hard-user</em>, que pode ser um conhecedor de informática ou alguém influente no meio <em>internautico</em>. Especulação, óbvio, mas as probabilidades realmente são altas.</p>
<p>Outra é que, para todos que já se divertiram com games, vem a sensação de ter encontrado uma &#8220;área secreta&#8221; do site, algo que estava ali só para <em>aqueles que conhecem o código</em>. Um bônus!</p>
<p>Mas, no fundo, ter o Konami Code ativado no seu site significa dizer: <em>nós também conhecemos o código!</em></p>
<p>Segue o script. Basta incluir este código e criar uma função com o nome &#8220;konamiFunction&#8221;. Ela será executada quando o código for digitado.</p>
<pre lang="javascript">var konami = "38384040373937396665", dkonami = "";
function konamiCode(e) {
var k = String(document.layers ? e.which : document.all ? event.keyCode : document.getElementById ? e.keyCode : "");
  if(k &amp;&amp; konami.indexOf(dkonami+k) == 0) dkonami += k;
	else dkonami = "";
	if(dkonami == konami) {
	  if(typeof konamiFunction == "function") konamiFunction();
	dkonami = "";
	}
}
document.onkeydown = konamiCode;</pre>
<p>Invente algo interessante e&#8230; Konami Code neles!</p>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2009/06/konami-code-em-sites-web/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>fakeFile: como estilizar um input type=file</title>
		<link>http://www.caugb.com.br/2008/11/fakefile-estilizar-um-input-file/</link>
		<comments>http://www.caugb.com.br/2008/11/fakefile-estilizar-um-input-file/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 20:19:13 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
				<category><![CDATA[Funções]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.caugb.com.br/?p=66</guid>
		<description><![CDATA[Pois é, essa era uma questão incômoda para mim até algum tempo atrás. É impossível! inputs com type=file não aceitam quase nenhuma regra CSS e, a não ser que estejamos trabalhando com formulários sem formatação, ficam sempre destoando, &#8220;quebrando&#8221; o &#8230; <a href="http://www.caugb.com.br/2008/11/fakefile-estilizar-um-input-file/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<form enctype="application/x-www-form-urlencoded" method="get">
<p>Pois é, essa era uma questão incômoda para mim até algum tempo atrás. É impossível! inputs com type=file não aceitam quase nenhuma regra CSS e, a não ser que estejamos trabalhando com formulários sem formatação, ficam sempre destoando, &#8220;quebrando&#8221; o layout do formulário.</p>
<p>Então, na busca de soluções possíveis, encontrei algumas baseadas <a href="http://www.quirksmode.org/dom/inputfile.html" class="http html external blank"  target="_blank">nessa lógica</a>, que pareceu ser a única viável e que consiste em tornar o input invisível com a propriedade opacity e e então colocá-lo por cima de uma imagem, que deve simular o elemento. Bacana, mas como cada browser renderiza o input de um jeito diferente (tamanhos do campo de texto e do botão), dificilmente a nossa imagem correspoderia ao tamanho do botão, o que provocaria confusões quanto ao local do clique.</p>
<p>    <span id="more-66"></span></p>
<p>Pensei então em acrescentar alguns detalhes que fizessem o input se adaptar à imagem ao invés de tentar fazer uma imagem que casasse com as proporções do input (que são variáveis). A idéia era fazer com que o botão do input ficasse num tamanho que cubrisse totalmente a imagem, mas dando um jeito de esconder a parte do input que excedeu a imagem.</p>
<p>Primeiro problema: posso definir altura e largura, mas como o texto no botão é sempre igual (Procurar&#8230;) eu conseguia apenas uma mudança disso:  </p>
<input size="20" type="file" />
<p>Para isso:    </p>
<input style="width: 300px; height: 70px;" size="20" type="file" />
<p>  Se temos uma imagem maior como esta: </p>
<p><img src="http://www.caugb.com.br/wp-content/uploads/2008/11/arquivo1.png" alt="" width="206" height="69" /> </p>
<p>certamente parte dela ficará insensível ao clique, pois a largura do botão continua a mesma &#8211; e só ele é sensível ao clique. Então, para mudar a largura do botão, podemos aumentar o tamanho da fonte! Ok, mas para que tamanho? um tamanho fixo não parecia muito legal&#8230; cheguei então à uma proporção que se mostrou correta nos meus testes: (largura da imagem / 5).</p>
<p>    E ao aumentar o tamanho da fonte, consigo algo assim:    </p>
<input style="font-size: 40px; width: 300px; height: 70px;" size="20" type="file" />
<p> Isso aumenta a largura do botão. Ok, agora precisamos colocar o input sobre a imagem, mas alinhado à direita para tirar a parte texto do input file de cima da nossa imagem. Aí resolvi criar uma função Javascript para fazer todo o necessário de uma vez. A lógica que usei foi a seguinte: </p>
<ul>
<li>Leio o tamanho da imagem</li>
<li>Crio um DIV exatamente do mesmo tamanho e com style=&#8221;position:relative; overlow:hidden;&#8221;</li>
<li>Insiro o DIV imediatamente antes da imagem</li>
<li>Coloco a imagem dentro do DIV</li>
<li>Calculo o tamanho da fonte para que a largura do botão cubra a imagem (FS = width/5 ( +/-&#8230; ))</li>
<li>Defino a propriedade style do input para &#8220;position:absolute; top:0; right:0; opacity:0; font-size:FSpx&#8221;</li>
<li>Coloco o input dentro do DIV</li>
</ul>
<p>
Bem, a função <code>fakeFile</code> recebe 3 parâmetros, sendo 2 obrigatórios: a imagem e o input file (como DOM objects) e um terceiro opcional que recebe um input file para receber o caminho para o arquivo a cada mudança no input file original. As funções <code>addEvent</code> e <code>$</code> são utilizadas por <code>fakeFile</code>, por isso foram também incluídas
</p>
<pre lang="javascript">function fakeFile(image, input, pathfield) {
var w = image.offsetWidth, h = image.offsetHeight,
    s = parseInt(w/4.2), wrapper = document.createElement('div');
wrapper.style.cssText = "position:relative; width:"+w+"px; height:"+h+"px; overflow:hidden; z-index:100;";
input.style.cssText = "position:absolute; height:"+h+"px; top:0; right:0; font-size:"+s+"px; "+
                      "filter:alpha(opacity=0); opacity:0; z-index:101;";
  if(pathfield)
    addEvent(input, 'change', new Function('$("'+pathfield.id+'").value = $("'+input.id+'").value;'));
image.parentNode.insertBefore(wrapper, image);
wrapper.appendChild(image);
wrapper.appendChild(input);
return wrapper;
}

function $(id) { return typeof(id) == 'object' ? id : (document.getElementById(id) || null); }

function addEvent(obj, evType, fn){
 if(obj.addEventListener) obj.addEventListener(evType, fn, false);
 else if(obj.attachEvent) obj.attachEvent("on"+evType, fn);
}</pre>
<p>Veja <a href="http://www.caugb.com.br/scripts/fake.php" class="http php internal blank"  target="_blank">aqui uma página</a> de exemplo.</p>
</form>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2008/11/fakefile-estilizar-um-input-file/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mostrar uma mensagem quando input está vazio</title>
		<link>http://www.caugb.com.br/2008/11/mostrar-uma-mensagem-quando-input-esta-vazio/</link>
		<comments>http://www.caugb.com.br/2008/11/mostrar-uma-mensagem-quando-input-esta-vazio/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 02:46:56 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
				<category><![CDATA[Funções]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.caugb.com.br/?p=58</guid>
		<description><![CDATA[Sabe aquelas caixas de busca que mostram, por exemplo, &#8220;Buscar&#8221; e que quando colocamos o foco, o texto some para escrevermos o que quisermos? Vamos mostrar aqui uma função javascript para aplicar essa funcionalidade a elementos input. A idéia é &#8230; <a href="http://www.caugb.com.br/2008/11/mostrar-uma-mensagem-quando-input-esta-vazio/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Sabe aquelas caixas de busca que mostram, por exemplo, &#8220;Buscar&#8221; e que quando colocamos o foco, o texto some para escrevermos o que quisermos? Vamos mostrar aqui uma função javascript para aplicar essa funcionalidade a elementos input.</p>
<p><span id="more-58"></span>A idéia é que a função recebe como parâmetros o elemento input e a mensagem a ser exibida quando não houver outro texto digitado e aplica isso ao input. Lá vai a função:<br />
 </p>
<pre lang="javascript">function msgIfEmpty(el, msg) {
var hasval = /\w/.test(el.value);
  if(!hasval) {
  el.value = msg;
  addClass(el, 'disabled');
  }
el.defaultValue = msg;
  el.onfocus = function() {
    if(this.value == this.defaultValue) {
    this.value = '';
    removeClass(this, 'disabled');
    }
  };
  el.onblur = function() {
    if(/^\s*$/.test(this.value)) {
    this.value = this.defaultValue;
    addClass(this, 'disabled');
    }
  };
}</pre>
<p>Começamos aplicando a mensagem como valor default do input (e como valor do atributo value se não há valor declarado). Então definimos funções para os eventos onfocus e onblur do elemento.</p>
<p>Adicionalmente, adicionamos a classe &#8216;disabled&#8217; quando a mensagem está sendo exibida. Para isso, usamos as funções (bastante conhecidas) <code>addClass </code>e <code>removeClass</code>, mostradas abaixo.</p>
<pre lang="javascript">function addClass(el, classn) {
removeClass(el, classn);
el.className += ' '+classn;
}

function removeClass(el, classn) {
  if (!(el &#038;&#038; el.className)) return;
var cls = el.className.split(/\s+/), ar = [];
  for(var i = cls.length; i > 0;) if(cls[--i] != classn) ar.push(cls[i]);
el.className = ar.join(" ");
}</pre>
<p>Essa é uma função simples e útil, poupando o trabalho de reescrever esse simples javascript em cada elemento. Veja um exemplo de uso <a href="http://www.caugb.com.br/scripts/msgifempty.html" class="http html internal blank"  target="_blank">aqui</a>.</p>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2008/11/mostrar-uma-mensagem-quando-input-esta-vazio/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Relógio digital em javascript, um exercício</title>
		<link>http://www.caugb.com.br/2008/03/relogio-digital-em-javascript-um-exercicio/</link>
		<comments>http://www.caugb.com.br/2008/03/relogio-digital-em-javascript-um-exercicio/#comments</comments>
		<pubDate>Tue, 25 Mar 2008 01:23:15 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
		
		<guid isPermaLink="false">http://www.caugb.com.br/blog/2008/03/24/relogio-digital-em-javascript-um-exercicio/</guid>
		<description><![CDATA[Há tempos que não escrevo por aqui, eu sei. É que tenho trabalhado muito&#8230; mas outro dia, para exercitar, para &#34;desopilar&#34; o cérebro, resolvi fazer um reloginho digital &#8211; sem usar texto, apenas DIVs &#8211; setando a cor das bordas. &#8230; <a href="http://www.caugb.com.br/2008/03/relogio-digital-em-javascript-um-exercicio/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Há tempos que não escrevo por aqui, eu sei. É que tenho trabalhado muito&#8230; mas outro dia, para exercitar, para &quot;desopilar&quot; o cérebro, resolvi fazer um reloginho digital &#8211; sem usar texto, apenas DIVs &#8211; setando a cor das bordas. Esse exercício resultou num documento HTML que pode facilmente ser usado em seu site.</p>
<p><span id="more-52"></span></p>
<p>Veja o código:</p>
<pre class="codigo" style="white-space:pre;">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&gt;
&lt;title&gt;Clock&lt;/title&gt;
&lt;style type="text/css" title="big"&gt;
#clock { background-color:#000; padding:5px; height:55px; width:242px; }
#clock #separator1, #clock #separator2 {
width:20px; padding-top:17px; text-align:center; float:left;
}
#clock #separator1 div, #clock #separator2 div {
width:0; height:0; border:3px solid #CCC; margin:10px 8px 10px 8px;
}
#clock .dig { width:29px; padding:0; float:left; }
#clock .mid { width:20px; height:18px; border:6px solid #CCC; }
#clock .up { border-bottom-width:3px; }
#clock .down { border-top-width:3px; }
#clock .mrig { margin-right:4px; }
#clock .mlef { margin-left:4px; }
&lt;/style&gt;
&lt;style type="text/css" title="small"&gt;
#clock { background-color:#000; padding:2px; height:23px; width:116px; }
#clock #separator1, #clock #separator2 {
width:7px; height:18px; padding-top:6px; text-align:center; float:left;
}
#clock #separator1 div, #clock #separator2 div {
width:0; height:0; border:1px solid white; margin:5px 2px 5px 1px;
}
#clock .dig { width:15px; padding:0; float:left; }
#clock .mid { width:10px; height:8px; border:2px solid white; }
#clock .up { border-bottom-width:1px; }
#clock .down { border-top-width:1px; }
#clock .mrig { margin-right:2px; }
#clock .mlef { margin-left:2px; }
&lt;/style&gt;
&lt;script type="text/javascript"&gt;
var _on = 'lightgreen', _off = '#000000', _tt = false;

function apply(digit, num) {
  if(/^d[1-6]$/.test(digit) == false) return;
  if(/^\d$/.test(num) == false) return;
var d = $(digit), divs = d.getElementsByTagName('div'), el1 = divs[0], el2 = divs[1],
    numbers = [
    [1,1,0,1,0,1,1,1], [0,1,0,0,0,1,0,0], [1,1,1,0,1,0,1,1], [1,1,1,0,1,1,1,0], [0,1,1,1,1,1,0,0],
    [1,0,1,1,1,1,1,0], [1,0,1,1,1,1,1,1], [1,1,0,0,0,1,0,0], [1,1,1,1,1,1,1,1], [1,1,1,1,1,1,0,0]
    ];
el1.style.borderTopColor =    numbers[num][0] ? _on : _off;
el1.style.borderRightColor =  numbers[num][1] ? _on : _off;
el1.style.borderBottomColor = numbers[num][2] ? _on : _off;
el1.style.borderLeftColor =   numbers[num][3] ? _on : _off;
el2.style.borderTopColor =    numbers[num][4] ? _on : _off;
el2.style.borderRightColor =  numbers[num][5] ? _on : _off;
el2.style.borderBottomColor = numbers[num][6] ? _on : _off;
el2.style.borderLeftColor =   numbers[num][7] ? _on : _off;
}

function tictac() {
var divs1 = $('separator1').getElementsByTagName('div');
  for(var i = 0; i &lt; divs1.length; i++)
    divs1[i].style.borderColor = _tt ? _off : _on;
var divs2 = $('separator2').getElementsByTagName('div');
  for(var i = 0; i &lt; divs2.length; i++)
    divs2[i].style.borderColor = _tt ? _off : _on;
_tt = (!_tt);
}

function setClock(color) {
var d = new Date(), h = d.getHours(), m = d.getMinutes(), s = d.getSeconds();
  if(h &lt; 10) h = '0'+h;
  if(m &lt; 10) m = '0'+m;
  if(s &lt; 10) s = '0'+s;
apply('d6', Number(String(s).substring(1,2)));
apply('d5', Number(String(s).substring(0,1)));
apply('d4', Number(String(m).substring(1,2)));
apply('d3', Number(String(m).substring(0,1)));
apply('d2', Number(String(h).substring(1,2)));
apply('d1', Number(String(h).substring(0,1)));
tictac();
setTimeout(setClock, 1000);
setTimeout(tictac, 500);
}

function $(id) {
return typeof(id) == 'object' ? id : (document.getElementById(id) || null);
}

function stl(s) {
var stls = document.getElementsByTagName('style');
  for(var i = 0; i &lt; stls.length; i++) stls[i].disabled = (stls[i].title != s);
}
&lt;/script&gt;
&lt;/head&gt;

&lt;body onload="setClock(); stl('big');"&gt;
  &lt;p style="clear:both; margin-bottom:20px"&gt;
    &lt;a href="javascript://" onclick="stl('big')"&gt;grande&lt;/a&gt; |
    &lt;a href="javascript://" onclick="stl('small')"&gt;pequeno&lt;/a&gt;
  &lt;/p&gt;
  &lt;div id="clock"&gt;
    &lt;div id="d1" class="dig mrig"&gt;
      &lt;div id="d1u" class="mid up"&gt;&lt;/div&gt;
      &lt;div id="d1d" class="mid down"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="d2" class="dig mlef"&gt;
      &lt;div id="d2u" class="mid up"&gt;&lt;/div&gt;
      &lt;div id="d2d" class="mid down"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="separator1"&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="d3" class="dig mrig"&gt;
      &lt;div id="d3u" class="mid up"&gt;&lt;/div&gt;
      &lt;div id="d3d" class="mid down"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="d4" class="dig mlef"&gt;
      &lt;div id="d4u" class="mid up"&gt;&lt;/div&gt;
      &lt;div id="d4d" class="mid down"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="separator2"&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="d5" class="dig mrig"&gt;
      &lt;div id="d5u" class="mid up"&gt;&lt;/div&gt;
      &lt;div id="d5d" class="mid down"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="d6" class="dig mlef"&gt;
      &lt;div id="d6u" class="mid up"&gt;&lt;/div&gt;
      &lt;div id="d6d" class="mid down"&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>        <!-- Links Classifier --></p>
<p>
	  <a href="http://www.caugb.com.br/scripts/clock.html" class="http html internal blank"  target="_blank">E aqui essa página carregada (em uma nova janela)</a></p>
<p>Abraços, Cau </p>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2008/03/relogio-digital-em-javascript-um-exercicio/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Suporte básico a i18n em PHP</title>
		<link>http://www.caugb.com.br/2008/01/suporte-basico-a-i18n-em-php/</link>
		<comments>http://www.caugb.com.br/2008/01/suporte-basico-a-i18n-em-php/#comments</comments>
		<pubDate>Thu, 10 Jan 2008 17:56:04 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
		
		<guid isPermaLink="false">http://www.caugb.com.br/blog/2008/01/10/suporte-basico-a-i18n-em-php/</guid>
		<description><![CDATA[Vou apresentar aqui uma classe para tradução a partir de catálogos .PO e .POT, compatíveis com o GNU GETTEXT, mas antes vamos falar um pouco sobre os conceitos envolvidos na internacionalização de sites e softwares. O termo &#34;i18n&#34; vem de &#8230; <a href="http://www.caugb.com.br/2008/01/suporte-basico-a-i18n-em-php/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Vou apresentar aqui uma classe para tradução a partir de catálogos .PO e .POT, compatíveis com o GNU GETTEXT, mas antes vamos falar um pouco sobre os conceitos envolvidos na internacionalização de sites e softwares.</p>
<p>O termo &quot;i18n&quot; vem de i + nternationalizatio (18 letras) + n &#8211; <em>internationalization</em> ou internacionalização. Mas há também o conceito de localização, ao qual nos referimos por &quot;l10n&quot; &#8211; <em>localization</em> e uma grande confusão quanto <a href="http://www.w3.org/International/questions/qa-i18n.pt.php" class="http php external blank"  target="_blank">às diferenças entre os dois</a>. Depois de ler o que <a href="http://pt.wikipedia.org/wiki/I18n" class="http external blank"  target="_blank">diz a wikipedia</a> ainda fiquei com dúvidas e foi <a href="http://www.w3.org/International/questions/qa-i18n.pt.php" class="http php external blank"  target="_blank">aqui</a> que tive um esclarecimento um pouco maior. Vou tentar resumir nas minhas palavras. </p>
<p><span id="more-51"></span></p>
<h3>Internacionalização</h3>
<p>O processo de internacionalização consiste em colocar seu software ao alcance da comunidade internacional, traduzindo a interface para outros idiomas e substituindo este ou aque detalhe específico do seu &quot;local cultural&quot; por versões aceitas internacionalmente &#8211; me refiro a coisas como formatos de valores e datas, por exemplo.</p>
<p>Este é um processo de abertura, que busca mais abrangência. Alcançar um público mais diverso, que está familiarizado com &quot;<em>multilanguage interfaces</em>&quot;.</p>
<p>A internacionalização é colocada como um estágio necessário à localização de um aplicativo. Localizar um aplicativo é algo que acontece com o tempo e se o aplicativo preenche certos requesitos, mas a internacionalização é  para ser incluída no momento de desenvolver o projeto. <br />
          &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<h3>Localização</h3>
<p>Aqui a direção se inverte. Enquanto a internacionalização anda em direção ao mundo, a localização se dirige a um local específico &#8211; usualmente um país, e deve englobar detalhes específicos da cultura local, como se tivesse sido feito para este público específico.</p>
<p>Aqui falamos de suporte a caracteres de outros alfabetos, direção do texto na página (<a href="http://he.wikipedia.com" class="http com external blank"  target="_blank">curiosidade: wikipedia em hebreu</a>)  , uso de linguagem local (pt_BR em vez de pt), imagens específicas, etc. </p>
<p>Isso inclui possívelmente a mudança do layout e outras coisas que vão além da simples tradução do texto.<br />
          &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; </p>
<p>Já viu que o que se faz em geral é a internacionalização, né? o processo de localizar um software para todas as mais relevantes culturas é apenas para sistemas operacionais e programas comerciais como photoshop, etc. Trata-se de um trabalho que inclui muita pesquisa e adaptações, às vezes pesadas, no software. </p>
<p>O PHP tem suporte nativo ao GetText do GNU, que usa arquivos .MO &#8211; binários compilados a partir de catálogos .PO. Legal, muito rápido por usar arquivos compilados. Mas quando tentei usar um esquema mais complexo, com múltiplos textdomains, me enrolei todo, achei complicado e sem documentação, principalmente em português. Como sempre acontece comigo, resolvi fazer eu mesmo um sistema e criei uma alternativa intermediária. </p>
<p>A classe i18n usa os catálogos PO sem compilação para fazer a tradução e trabalha com múltiplos textdomains sem complicação. Através de i18n::parsePoFile() podemos parsear os arquivos e extrair as mensagens para usá-las na tradução. </p>
<p>Uma vantagem é preservar a possibilidade de usar editores como o <a href="http://www.poedit.net/" class="http external blank"  target="_blank">PoEdit</a> para ler as mensagens nos arquivos fonte e editar a tradução normalmente. Apenas na hora de ler nós faremos isso por nossa conta. É bom lembrar que para usar domínios diferentes para traduzir os mesmos arquivos, ao ler as mensagens, o PoEdit irá ignorar os domínios e acrescentar todas as mensagens a cada domíno &#8211; o ideal é usar domínios diferentes para diretórios diferentes (que não estejam contidos um no outro). </p>
<p>Como vamos usar o catálogo sem compilação, <em>human-readable</em>, não precisaremos ocupar espaço com os arquivos .MO que o PoEdit gera automaticamente, a não ser que queiramos usar ambos os métodos simultaneamente &#8211; o que é possível. Nesse caso, usaremos como domínio principal do i18n um domínio diferente do setado com bindtextdomain(). E podemos usar quantos textdomains quisermos no i18n, preservando o domínio principal para a função gettext() do PHP. </p>
<p><a href="http://www.caugb.com.br/scripts/i18n/" class="http internal blank"  target="_blank">Código e exemplo da classe i18n</a> </p>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2008/01/suporte-basico-a-i18n-em-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Múltiplas funções para os eventos em elementos HTML</title>
		<link>http://www.caugb.com.br/2007/11/multiplas-funcoes-para-os-eventos-em-elementos-html/</link>
		<comments>http://www.caugb.com.br/2007/11/multiplas-funcoes-para-os-eventos-em-elementos-html/#comments</comments>
		<pubDate>Thu, 29 Nov 2007 10:37:32 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
		
		<guid isPermaLink="false">http://www.caugb.com.br/blog/2007/11/29/multiplas-funcoes-para-os-eventos-em-elementos-html/</guid>
		<description><![CDATA[Já havia me deparado com esse problema algumas vezes e sempre contornava, sem pensar em uma solução. Acontece que estou no meio da organização de uma biblioteca js &#8211; algo que me evite a criação de um novo arquivo js &#8230; <a href="http://www.caugb.com.br/2007/11/multiplas-funcoes-para-os-eventos-em-elementos-html/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Já havia me deparado com esse problema algumas vezes e sempre contornava, sem pensar em uma solução. Acontece que estou no meio da organização de uma biblioteca js &#8211; algo que me evite a criação de um novo arquivo js com as mesmas funções a cada novo projeto. Bem, o fato é que novamente encontrei a mesma dificuldade&#8230; vou criar um exemplo simples para explicar. Supondo que temos as seguintes funções:</p>
<p><span id="more-50"></span></p>
<pre lang="javascript">function toRed() {
this.style.color = &quot;red&quot;;
}
function toBlue() {
this.style.color = &quot;blue&quot;;
} </pre>
<p>Então pego um div e copio as funções para os eventos mouseover e mouseout:</p>
<pre lang="javascript">var div = document.getElementById('meudiv');
div.onmouseover = toRed;
div.onmouseout = toBlue; </pre>
<p>Bacana, isso vai funcionar que é uma beleza. Mas durante a navegação, meu visitante executou uma ação que precisou adicionar mais um comando ao evento mouseover do mesmo div, mas não quero perder as ações que já estão lá. Se usar novamente comandos como os que usei acima, a função será substituída pela nova&#8230; Aí lembrei daquela famosa função  <a href="http://www.dustindiaz.com/top-ten-javascript/" class="http external blank"  target="_blank">addEvent()</a>, que usa os métodos <code>addEventListener</code> ou <code>attachEvent</code>,  isso tanto   para objetos tipo <code>Object</code> quanto para elementos HTML, &quot;pegos&quot; via DOM. Bem, funcionou, as funções foram executadas, mas aí eu fiz a incrível descoberta de que esses métodos não criam uma propriedade no elemento com a função enviada. Ao invés disso, ela é executada &quot;externamente ao objeto&quot;, portanto a minha <a href="http://www.caugb.com.br/blog/2007/11/26/como-usar-o-this-em-javascript/" class="http internal self" >palavra <em>this</em></a>  não aponta para o meu elemento, mas para o objeto <code>window</code>. </p>
<p>Bolei então um modo de resolver essa situação criando uma propriedade chamada <code>events</code> no elemento. É um objeto que vai armazenando as funções registradas para os eventos e para gerenciar isso vamos inserir alguns novos métodos no elemento: <code>addEvent, removeEvent, clearEvent, hasEvent e fireEvent</code>. Para que  tudo aconteça, criamos a  função <code>elementEvents</code>, que aplica os novos métodos ao elemento enviado &#8211; e função <code>extendAll</code> apenas para aplicar a primeira a todos os elementos da página. Veja o código:</p>
<pre lang="javascript">function elementEvents(el) {
  el.addEvent = function addEvent(evname, func) {
  evname = /^on/.test(evname) ? evname : &quot;on&quot;+evname;
  var fire = new Function(&quot;e&quot;, &quot;this.fireEvent(\&quot;&quot;+evname+
                               &quot;\&quot;, e || window.event);&quot;);
    if(typeof this.events == &quot;undefined&quot;) this.events = {};
    if(typeof this.events[evname] == &quot;undefined&quot;)
      this.events[evname] = [];
    if(typeof this[evname] == 'function' &#038;&#038;
       this[evname].toString() != fire.toString())
      this.events[evname].push(this[evname]);
    if(!this.hasEvent(evname, func)) this.events[evname].push(func);
  this[evname] = fire;
  return this;
  };

  el.removeEvent = function (evname, func) {
  evname = /^on/.test(evname) ? evname : &quot;on&quot;+evname;
    if(typeof this.events == &quot;undefined&quot; ||
       typeof this.events[evname] == &quot;undefined&quot; ||
       !this.events[evname].length) return this;
  var ret = [];
    for(var i = 0; i < this.events[evname].length; i++)
      if(this.events[evname][i].toString() != func.toString())
        ret.push(this.events[evname][i]);
  this.events[evname] = ret;
  return this;
  };

  el.clearEvent = function (evname) {
  evname = /^on/.test(evname) ? evname : &quot;on&quot;+evname;
    if(typeof this.events == &quot;object&quot; &#038;&#038;
       typeof this.events[evname] != &quot;undefined&quot; &#038;&#038;
       this.events[evname].length) delete(this.events[evname]);
  this[evname] = null;
  return this;
  };

  el.hasEvent = function (evname, func) {
  evname = /^on/.test(evname) ? evname : &quot;on&quot;+evname;
    if(typeof this.events == &quot;undefined&quot; ||
       typeof this.events[evname] == &quot;undefined&quot; ||
       !this.events[evname].length) return false;
    for(var i = 0; i < this.events[evname].length; i++)
      if(this.events[evname][i].toString() == func.toString())
        return true;
  return false;
  };

  el.fireEvent = function (evname, ev) {
  evname = /^on/.test(evname) ? evname : &quot;on&quot;+evname;
    if(typeof this.events[evname] == &quot;undefined&quot;) return true;
    for(var i = 0; i < this.events[evname].length; i++) {
      if(typeof this.events[evname][i] == &quot;function&quot;) {
      this.tempFunction = this.events[evname][i];
      this.tempFunction(ev);
      }
    }
  };
return el;
}

function extendAll() {
var els = document.getElementsByTagName(&quot;*&quot;);
  for(var i = 0; i < els.length; i++) elementEvents(els[i]);
}

// window.onload = extendAll;
// ou...
// addEvent(window, 'load', extendAll);</pre>
<p>As últimas linhas mostram duas maneiras diferentes de aplicar a função extendAll ao evento onload do objeto window, fazendo com que os mátodos sejam aplicados a todos os elementos da página. Mas podemos usar o sistema em um elemento específico... veja:</p>
<pre lang="javascript">var div = document.getElementById('meudiv');
elementEvents(div);
div.addEvent('mouseover', toRed);
div.addEvent('mouseout', toBlue);
div.addEvent('mouseover',
             function() {
             this.style.border = &quot;2px solid #666&quot;;
             });
div.addEvent('mouseout',
             function() {
             this.style.borderWidth = &quot;0px&quot;;
             });</pre>
<p>Após esses comandos, a propriedade <code>events</code> do div estará com a seguinte anatomia:</p>
<pre lang="javascript">{
  'mouseover': [
    function() { this.style.color = &quot;red&quot;; },
    function() { this.style.border = &quot;2px solid #666&quot;; }
  ],
  'mouseout': [
    function() { this.style.color = &quot;blue&quot;; },
    function() { this.style.borderWidth = &quot;0px&quot;; }
  ]
}
</pre>
<p>As funções de cada evento serão executadas na seqüência do array de funções, mas até aí nada... se simplesmente executarmos as funções num loop, o <em>this</em> ainda não estará apontando para o elemento. A mágica está no método <code>tempFunction</code>, criado em <code>fireEvent</code>, que recebe a função e a executa como parte do objeto. Isso faz com que o evento seja repassado corretamente (inclusive para IE) e que a palavra this aponte para o próprio elemento. </p>
<p>Veja <a href="http://www.caugb.com.br/scripts/elementevents/" class="http internal self" >aqui uma página de testes</a> </p>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2007/11/multiplas-funcoes-para-os-eventos-em-elementos-html/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Como usar o this em Javascript</title>
		<link>http://www.caugb.com.br/2007/11/como-usar-o-this-em-javascript/</link>
		<comments>http://www.caugb.com.br/2007/11/como-usar-o-this-em-javascript/#comments</comments>
		<pubDate>Mon, 26 Nov 2007 19:07:02 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
		
		<guid isPermaLink="false">http://www.caugb.com.br/blog/2007/11/26/como-usar-o-this-em-javascript/</guid>
		<description><![CDATA[Usar o this no javascript é uma mão na roda, mas pode ser bastante confuso para quem está começando. &#34;this&#34; traduzido significa isso/isto &#8211; não sei bem, mas um desses (ou ambos). Em Javascript, quando usamos a palavra-chave this, estamos &#8230; <a href="http://www.caugb.com.br/2007/11/como-usar-o-this-em-javascript/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Usar o <em>this</em> no javascript é uma mão na roda, mas pode ser bastante confuso para quem está começando. &quot;this&quot; traduzido significa isso/isto &#8211; não sei bem, mas um desses (ou ambos). </p>
<p>Em Javascript, quando usamos a palavra-chave <em>this</em>, estamos criando uma referência ao objeto que contém o método em execução. Objeto, método&#8230; mas e se estivermos falando de uma função normal? Pois é&#8230; aí é hora de entender algumas coisinhas. </p>
<p><span id="more-49"></span></p>
<p>Em Javascript tudo são objetos, métodos e propriedades. Quando declaramos uma variável com o valor &quot;a&quot;, criamos automaticamente uma instância do objeto <code>String</code>. Se o valor for 1 o objeto instanciado será o <code>Number</code> e assim por diante. Quando escrevemos uma função como no exemplo a seguir </p>
<pre lang="javascript">function showmsg(msg) { alert(msg); }</pre>
<p>criamos uma instância do objeto <code>Function</code>, exatamente como com as variáveis. Por isso podemos declarar a mesma função assim: </p>
<pre lang="javascript">var showmsg = function(msg) { alert(msg); };</pre>
<p> e como o objeto pai é naturalmente o <code>window</code>, as duas formas mostradas equivalem a </p>
<pre lang="javascript">window.showmsg = function(msg) { alert(msg); };</pre>
<p>pois tudo que é declarado &quot;solto&quot;, sem ser colocado explicitamente num objeto, é adicionado ao objeto <code>window</code>, e assim tudo são métodos e propriedades de objetos. Compreendido isso, vamos ao <em>this</em>.</p>
<p>A pergunta é: para que objeto o <em>this</em> está apontando no contexto em que está sendo usado? </p>
<p>No caso de um elemento HTML, o <em>this</em> irá sempre apontar para o próprio elemento, pois o texto das propriedades relativas a eventos nas TAGs é lido como função interna do objeto. Veja:</p>
<pre> &lt;div id=&quot;md&quot; onclick=&quot;this.style.color = &quot;blue&quot;;&quot;&gt;...&lt;/div&gt;</pre>
<p>Ou poderíamos usar uma função, atribuindo-a ao evento onclick dinamicamente:</p>
<pre lang="javascript">function setcolor() { this.style.color = &quot;blue&quot;; }
document.getElementById(&quot;md&quot;).onclick = setcolor;</pre>
<p>Isso funcionaria do mesmo jeito, só que assim podemos aplicar a qualquer elemento a função  que ela vai funcionar legal. O <em>this</em> irá apontar para o elemento que chamou a função. Mas o código abaixo não iria funcionar como esperado&#8230; </p>
<pre>&lt;div id=&quot;md&quot; onclick=&quot;setcolor()&quot;&gt;...&lt;/div&gt;</pre>
<p>Por que não? Pelo mesmo motivo que isso não iria funcionar:</p>
<pre lang="javascript">document.getElementById(&quot;md&quot;).onclick = function()
                                        { setcolor(); };</pre>
<p> A função tem que ser um método do objeto  para que o <em>this</em> aponte para o próprio.  Há um meio fácil para ver se o <em>this</em> irá ou não funcionar: a palavra this deve estar contida no texto da função. Veja: </p>
<pre lang="javascript">var elem = document.getElementById(&quot;md&quot;);
alert(elem.onclick);</pre>
<p>Para os primeiros exemplos (os corretos), o código acima iria mostrar:</p>
<blockquote>
<p>function() { <strong>this</strong>.style.color = &quot;blue&quot;; }</p>
</blockquote>
<p>Enquanto os dois últimos exemplos (errados) iriam mostrar:</p>
<blockquote>
<p>setcolor();</p>
</blockquote>
<p>Como vemos, a palavra <em>this</em> não faz parte do texto da função nos últimos casos, portanto não irá apontar para o objeto DOM referente. As funções seriam executadas normalmente, mas o <em>this</em> iria se referir ao objeto        <code>window</code>        e como não existe a propriedade <code>style.color</code> lá, nada aconteceria. </p>
<p>Ao criar objetos explicitamente, podemos usar o <em>this </em>para referir o próprio objeto, mas atenção para a interação entre objetos, pois a função é copiada e será executada no novo contexto exatamente como foi escrita, portanto o alvo do <em>this</em> pode mudar de repente. Veja:</p>
<pre lang="javascript">var X = { &quot;a&quot;: 1,
          &quot;b&quot;: function() { alert(this.a+&quot;:&quot;+X.a); } };
X.b(); // mostra &quot;1:1&quot;
var Y = {&quot;a&quot;: 2, &quot;b&quot;: X.b }; // copio o método de X
Y.b(); // mostra &quot;2:1&quot; - this aqui é Y, e não mais X</pre>
<p>
Portanto, pode ser mais seguro usar o nome do objeto no lugar do this nesses casos.</p>
<p>E o uso do <em>this</em> em funções para manipulá-las como objetos? Como foi explicado, ao criar uma &quot;função solta&quot;, estamos na verdade criando um novo método no objeto <code>window</code>, portanto o <em>this</em> nesse contexto iria apontar para <code>window</code>. Para evitar isso, existe o operador <em>new</em>. Veja: </p>
<pre lang="javascript">function testThis() {
  if(typeof this.navigator != &quot;object&quot;)
	  this.navigator = {
      userAgent: &quot;com o operador new, this &quot;+
                 &quot;aponta para a própria função!&quot;
    };
val = this.navigator.userAgent;
}
function test1() { testThis(); alert(val); };function test2() { new testThis(); alert(val); };
</pre>
<p>Se testarmos as funções <code>test1</code> e <code>test1</code>, veremos que o mesmo <em>this</em> aponta para objetos diferentes, dependendo da forma que foi executada a função <code>testThis</code>. Se usar o operador <em>new</em>, isso faz o <em>this</em> referenciar a própria função como um objeto, senão <em>this</em> irá apontar para o objeto padrão <code>window</code>. </p>
<p>Interessante notar que os métodos <code>attachEvent</code> (IE) e <code>addEventListener</code> criam uma referência à função enviada, portanto ao usar a famosa função <code><a href="http://www.dustindiaz.com/top-ten-javascript/" class="http external blank"  target="_blank">addEvent()</a></code> para definir funções para eventos de objetos DOM, lembre que o <em>this</em> irá sempre apontar para o objeto <code>window</code>. </p>
<p>Bem, espero ter lançado alguma luz sobre o <em>this,</em> ao menos para os que estão iniciando.</p>
<p>Se você lê inglês, veja essa página: <a href="http://www.quirksmode.org/js/this.html" class="http html external blank"  target="_blank">www.quirksmode.org/js/this.html</a></p>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2007/11/como-usar-o-this-em-javascript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Uma classe em JS para manipular elementos SELECT</title>
		<link>http://www.caugb.com.br/2007/11/uma-classe-em-js-para-manipular-elementos-select/</link>
		<comments>http://www.caugb.com.br/2007/11/uma-classe-em-js-para-manipular-elementos-select/#comments</comments>
		<pubDate>Sun, 11 Nov 2007 13:22:52 +0000</pubDate>
		<dc:creator>caugbr</dc:creator>
		
		<guid isPermaLink="false">http://www.caugb.com.br/blog/2007/11/11/uma-classe-em-js-para-manipular-elementos-select/</guid>
		<description><![CDATA[Há pouco tempo escrevi um post mostrando como adicionar e retirar options de um select. Depois disso, construí um plugin para WordPress (mais um&#8230;) que usa e abusa dos selects. Depois de tudo pronto, fiquei pensando em como seria prático &#8230; <a href="http://www.caugb.com.br/2007/11/uma-classe-em-js-para-manipular-elementos-select/">Continuar lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Há pouco tempo escrevi um <a href="http://www.caugb.com.br/blog/2007/10/09/adicionar-ou-retirar-options-de-um-select/" class="http internal self" >post</a> mostrando como adicionar e retirar options de um select. Depois disso, construí um <a href="http://www.caugb.com.br/blog/wp-plugins/wp-roles/" class="http internal self" >plugin</a> para WordPress (mais um&#8230;) que usa e abusa dos selects. Depois de tudo pronto, fiquei pensando em como seria prático ter uma <em>library</em> em Javascript para manipular esse elemento. Comecei então a esboçar o script com base em funções que eu já tinha prontas, mas na forma de uma classe, para ser manuseado como objeto.</p>
<p><span id="more-48"></span></p>
<p>Em dois fins de semana (pois é, quando posso fazer algo pra relaxar de tanto código, muitas vezes escolho programar&#8230;) <a href="http://www.caugb.com.br/scripts/select/select.js" class="http js internal self" >este script</a> nasceu e cresceu. Naturalmente ainda faltam algumas coisas, como meios melhores de manusear os elementos OPTGROUP, por exemplo.</p>
<p>Os métodos atuias são os seguintes:</p>
<ul>
<li>create</li>
<li> addOptionAt</li>
<li>addOption</li>
<li>clone</li>
<li>extract</li>
<li>build</li>
<li>removeAllOptions</li>
<li>hasOption</li>
<li>selectAll</li>
<li>unselectAll</li>
<li>selectByVal</li>
<li>findText</li>
<li>removeOption</li>
<li>removeSelectedOptions</li>
<li>getSelectedIndexes</li>
<li>applyStyle</li>
<li>setStyle</li>
<li>transferSelectedOptions</li>
<li>sortOptions</li>
<li>addOptgroup</li>
<li>removeOptgroup</li>
<li>extractGroups</li>
<li>applyGroups</li>
<li>selectedToGroup</li>
</ul>
<p>Não vou escrever uma referência dos métodos, por falta de tempo, principalmente, mas você pode ver <a href="http://www.caugb.com.br/scripts/select/" class="http internal blank"  target="_blank">uma página de testes aqui</a>, com exemplos interessantes para entender como a coisa funciona. Há alguns comentários no próprio script, mas (talvez infelizmente&#8230;) estão em inglês&#8230;</p>
<p>Dúvidas e esclarecimentos podem ser resolvidos aqui, nos comentários, ok?<br />
Espero que este script seja útil.  </p>

<!-- Links Classifier - WordPress plugin -->
]]></content:encoded>
			<wfw:commentRss>http://www.caugb.com.br/2007/11/uma-classe-em-js-para-manipular-elementos-select/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

