HTML 5/ HTML5 / CSS3/ JQuery/ Web 2.0

10 mitos da incompatibilidade nos navegadores para HTML/CSS/JS

Quem anda de cabresto, sempre tende a olhar para baixo, excluindo a curiosidade de olhar o mundo exterior ao seu redor, depois que eu saltei da minha zona de conforto a 10 meses atrás, eu tinha a notória sensação de que eu descobria coisas novas a cada segundo, e as lembranças da zona de conforto me acomodaram mal, muito mal por sinal.
Uma das coisas que te deixam infeliz é a tal preguiça de inovar, justamente por que confortavelmente você acha que nunca precisa mudar, e nessa migração constante deparamos com mitos criados ou expurgados por quem não dá a mínima atenção em inovar e ser competitivo.

Quando eu comecei a estudar HTML5/CSS3/JS, eu tinha aquela sensação de mal estar adquirido, achando que nada prestava, tudo precisava melhorar, CSS então era a brincadeira de estica e puxa,Deus nos acuda!

Ao passar das semanas eu fui percebendo que os navegadores evoluíram bastante, frameworks e desenvolvedores de padrões web colaboraram para essas evoluções e no final percebi que quem estava atrasado na história era eu mesmo.

Então somei o que eu achava mito e decidi escrever esse post para você abrir sua mente e se liberar de seus medos.

10 Mitos da incompatibilidade nos navegadores

MITO 1 – HTML e CSS é feito para fazer sites e não sistemas.

Resposta: Então você nunca usou o Hotmail, Gmail, adWords, adSense na vida, você nunca usou itaú bankline, Bradesco on-line e por ai vai. o HTML e CSS é poli valente, funciona para tudo.

MITO 2 – Tenho que fazer vários ifs e elses para suportar N navegadores

Resposta: Não há necessidade, já que existem N frameworks no mercado que fazem a manipulação perfeita entre engines de navegadores, grande parte dos navegadores usam webkit/gecko e o único a usar um engine diferente é o IE com seu msie, porém na última versão 8, já vem com suporte a padrões web.

Frameworks que podem te ajudar a quebrar esse mito: JQuery, MooTools, EXT Js, Script.aculo.us, ProtoType.

Ou seja, alternativas é o que não falta para esse mito, já que todos peleijam em achar que irá voltar a época das cavernas por manipular DOM de cada engine de navegador.

MITO 3 – HTML5 é incompatível com navegadores

Respota: Desde quando HTML é incompatível com navegadores? HTML5 nada mais é que uma nova versão do HTML, existem alguns recursos como WebGL, Canvas, Audio, Video, codecs de audio e video que são específicos de cada navegador, que ao total 93% de todos os recursos que você vai usar em um único projeto é compatível com todos os navegadores.

Caso você ainda tenha problemas em achar que o HTML5 pode não rodar perfeitamente no IE7,8 você pode usar bibliotecas já prontas para isso. Uma delas inclusive é amplamente utilizada, a Modernizr.

MITO 4 – Não posso usar MVC em uma aplicação web feita em Javascript e HTML

Resposta : Mito detonado, no bom estilo caçadores de mitos, desde que javascript é javascript, e tudo é Objeto. Então eu manipulo qualquer objeto aplicando qualquer padrão existente, Aconselho você usar esse slides para te influenciar a pensar diferente.

MITO 5 – Não consigo criar interfaces com facilidade como no Flex

Resposta: É por que você não conhece o JQuery UI, YUI, Prototype UI, UKI, MochaUI, Livepipe UI, Alloy UI e GWT. Ou seja, alternativas para você criar interfaces não faltam.

MITO 6 – Aplicações Web feitas em HTML 5 e CSS3 não são cross-plataforma.

Resposta: Navegadores hoje são cross-plataformas, rodam no Linux, MAC, Windows, ios, Android e Windows Phone. Se sua aplicação fica na caixinha de areia do navegador então ela também será cross-plataforma, não tendo a necessidade absoluta de portar seu aplicativo para diferentes plataformas. Assim como no Flash Player ser cross-plataforma, é por que ele tira proveito dos navegadores.

MITO 7 – Aplicações feitas em HTML5 e CSS3 são lentas

Resposta: Uma vez que sua aplicação pronta, ela trafega muito mais rápido para o navegador do usuário do que seu SWF, já que não é compilável, é apenas lida.
O Flex compila o que você escreve em um SWF, esse SWF é binário, como uma imagem em JPEG ou PNG é. A diferença é que uma vez baixado ele se torna mais rápido por que não é interpretado. Já com HTML, CSS e JS ele é interpretado sempre que você manipula.

A grande vantagem está no tráfego de dados e na re-utilização do sistema, á que por padrão ele tem cache ativo. roda muito mais macio no navegador e não depende de plug-in.

MITO 8 – Em aplicações Web eu não consigo fazer Sockets, usar o AMF

Resposta: Você consegue sim, WebSockets são novidade, são feitos em js, veja o Node.JS. E AMF conheça o AMFJs.

MITO 9 – As IDE atuais são péssimas, produtividade ZERO

Resposta: Mito detonado também, existem N IDEs excelentes uma delas é as IDEs feitas pela JetBrains, compatíveis com os padrões do mercado e cheia de recursos, outras tão boas são para o Eclipse como o Aptana. E claro o Dreamweaver CS5.

MITO 10 – Meus aplicativos são re-escritos sempre que for criar uma versão mobile deles.

Resposta: Existem 2 posibilidades de você usar HTML, CSS e JS em aplicações Móveis, uma é usar os Media-Queries de CSS, fazendo o layout de suas aplicações responsivas. Ou criando um aplicativo específico para Mobile usando o mesmo HTML 5 e CSS3 feito para versão Web/Desktop.

Então se você chegou até aqui, é sinal que alguns mitos já passaram por sua cabeça e a dúvida pairava no ar. A minha sugestão é, ajude outras pessoas a se libertar desses mitos.

HTML 5/ JQuery/ JQuery Mobile/ Playbook

jQuery Mobile 1.0 lançado

O suporte a CSS3 e HTML5 para dispositivos móveis é espantoso, 98% dos dispositivos tem suporte a todas as tecnologias web standards.

E o JQuery Mobile 1.0 está ai para provar isso.

Com sua recém lançada versão para o mercado, incrivelmente dá suporte a diversos dispositivos desde, iPads, iphones, blackberrys, androids, nokia e até web os.
Eu estudei e testei ele uns 6 meses atrás, acabei fazendo alguns testes que você pode conferir aqui do seu device., quando foi lançada a versão alpha, eu vi potêncial, porém na época era pouco provável adota-lo em uma solução comercial. Isso acaba por desmoronar, pelo que eu andei lendo dessa versão final.

Mesmo tendo sua versão mais estável lançada hoje, incrivelmente você já vê um número de soluções feitas com jQuery Mobile nesse site, chamado JQuery Mobile Gallery.

O que me impressiona nesse projeto é a velocidade de desenvolvimento e sua documentação. Que é ultra intuitiva.

Convido você a olhar de perto esse projeto e considera-lo, já que você conta com todo o poder do framework JQuery, fora os 250 mil plug-ins para plataforma.

Flex/ Flex 4/ Flex 4.5/ JQuery

Redescobrindo o gosto pelos padrões Web : JQuery para devs Flex – Parte 4

Estou fascinado como ambas tecnologias possuem suas particularidades e ao mesmo tempo compartilham tantas coisas em comum. Se por um lado aprender Javascript é parte fundamental para seu progresso com JQuery, serve a mesma deixa para Flex, que depende exclusivamente de Actionscript.

Embora a zona de conforto que o Flex lhe proporciona como design padrão já pre-definido, layout Manager já ajustadinho para qualquer tela, composição de componentes, arquitetura componentizada, tudo isso acarreta na escolha de se adotar ou não JQuery e padrões Web em seus projetos e em sua carreira profissional.

Fato é, que da uma preguiça fora de sério aprender tudo isso novamente, como denominar dependências e heranças com DOM, live encoding. É deverás complicado para quem sai de outro idioma programático e cai de pará-quedas no ambiente do navegador.

Nessa quarta parte, quero mostrar em diante como é a estrutura padrão de eventos no JQuery e como isso pode encurtar pontos no aprendizado.

Eventos

A gramática de eventos no Flex é composta por pacotes e mais pacotes definhados por componentes e seus containers, tanto que é muito bem distribuído, é como se fosse 1 caixa de palito de fósforo, contendo palitos com respectivas funções programáticas, um para cada tipo de fogo que se pretende ascender.
É estimado que por padrão no Flex 4.5 existam cerca de 98 tipos de evento, boa parte eles são herdeiros do evento chave que fica no pacote flash.events.Event os demais são de uso exclusivo de cada plataforma como AIR e Flash Player.

Já a gramática de eventos do JQuery, é um tanto simplificada, onde não passa mais que 36 tipos eventos, todos herdeiros de um só evento pai que é amarrado ao HTML, o DOM Object.

Porém, essa maneira simplista da coisa tem seu certo fundo técnico, uma vez que você tem N tipos de navegadores com N tipos de engine, ou você simplifica a coisa ou acaba fadado ao fracasso. Não tão distante, por mais que você queira relutar, os eventos no Flex também seguem um padrão cronológico ou técnico possa se dizer, do modelo de DOM level 3. Onde há uma certa semelhança em nomenclatura e a estrutura de como funciona, tal como adicionar listener, remover listener.

O que o JQuery fez foi pegar tudo isso e simplificar o máximo possível, trazendo ao desenvolvedor maior facilidade nessa execução de eventos. Porém em contra partida ele pecou pela exclusão do processo de fase, o que é umas das partes fundamentais em aplicações que tomam por base eventos.

Exemplo prático:

Criar um Div ( Bloco), onde ele siga a posição do mouse. Uns dos segredos desse exemplo é o CSS, com seu subselector position:relative;

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<style type="text/css">
.bloco {width:200px; height:200px; background:#000; display:block; position:relative;}
</style>
<script type="text/javascript">
 
	$(document).ready(function(e) {
 
		// começar a brincadeira com JQuery
 
			$(document).mousemove(function(e) {
                	$(".bloco").css("left",e.pageX);
					$(".bloco").css("top",e.pageY);
					var nova_cor = 'rgb(' + (Math.floor((-256)*Math.random()) + 200) + ','
                     + (Math.floor((-55)*Math.random()) + 200) + ','
                     + (Math.floor((-55)*Math.random()) + 200) + ')';
					$(".bloco").css("background",nova_cor);
            });
			$(document).mouseout(function(e) {
               setInterval(loop,4000);
            });
 
			function loop()
			{
				$(".bloco").animate({left:Math.random()*  screen.availWidth/2},1000);
				$(".bloco").animate({top:Math.random()* screen.height/2},1000);
			}
 
    });
</script>
</head>
 
<body>
			<div class="bloco"></div>
</body>
</html>

Se eu fizer esse exemplo no Flex, como seria?

 
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="init(event)">
 
	<fx:Declarations>
		<s:Move id="mover" target="{bloco}" duration="4000" />
	</fx:Declarations>
	<fx:Script>
		<![CDATA[
			import mx.events.EffectEvent;
			import mx.events.FlexEvent;
			import mx.events.FlexMouseEvent;
 
			protected function init(event:FlexEvent):void
			{
				this.addEventListener(MouseEvent.MOUSE_MOVE,mudarBloco);
				this.addEventListener(MouseEvent.ROLL_OUT,randomizar);
				this.addEventListener(MouseEvent.ROLL_OVER,pegarListeners);
 
			}
 
			protected function mudarBloco(event:MouseEvent):void
			{
				bloco.x = mouseX;
				bloco.y = mouseY;
				cor.color = Math.random()*0xffffff;
			}
 
			protected function randomizar(event:MouseEvent):void
			{
				mover.xTo = Math.random()* screen.width/2;
				mover.yTo = Math.random()* screen.height/2;
				mover.play();
				this.removeEventListener(MouseEvent.ROLL_OUT,randomizar);
 
			}
 
			protected function pegarListeners(event:MouseEvent):void
			{
				// TODO Auto-generated method stub
 
				this.addEventListener(MouseEvent.ROLL_OUT,randomizar);
			}
 
		]]>
	</fx:Script>
	<s:Rect id="bloco" width="200" height="200">
		<s:fill>
				<s:SolidColor id="cor"/>
		</s:fill>
	</s:Rect>
</s:Application>

Viu que tudo não passa de mousemove, mouseOut, posição do mouse. Tudo é igual, o que realmente muda nesse exemplo é a nomenclatura das palavras chaves usadas.

Uma simples lista de tarefa no JQuery

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<link href="css/padrao.css" rel="stylesheet" type="text/css">
 
<script type="text/javascript">
 
	$(document).ready(function(e) {
 
			$("#btn").click(function(e) {
                	// adicionar itens
					$("#tarefas").append('<li><input name="Tete" type="checkbox" value="'+$('input').val()+'"><label>'+$('input').val()+'</label></li>');
					$('input').val('');
					$('input').focus();
            });
    });
</script>
</head>
 
<body>
<input class="input" name="tarefa" type="text" lang="pt" value="Digite sua tarefa" size="30" maxlength="50">
<a id="btn" class="button green large">+</a>
 
<ul id="tarefas" class="lista">
</ul>
</body>
</html>

Até ai tudo bem, e se você quiser dinamicamente adicionar um evento sempre que um novo item é adicionado, você faz através do evento bind (), que é próprio para isso.

					$('li input').bind('change',function (e){
						if($("li input").is(':checked')){
							$(this).toggle();
						}
					});

O código fica no final

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<link href="css/padrao.css" rel="stylesheet" type="text/css">
 
<script type="text/javascript">
 
	$(document).ready(function(e) {
 
			$("#btn").click(function(e) {
                	// adicionar itens
					$("#tarefas").append('<li><input name="Tete" type="checkbox" value="'+$('input').val()+'"><label>'+$('input').val()+'</label></li>');
 
					$('li input').bind('change',function (e){
						if($("li input").is(':checked')){
							$(this).toggle();
						}
					});
					$('input').val('');
					$('input').focus();
            });
 
    });
</script>
</head>
 
<body>
<input class="input" name="tarefa" type="text" lang="pt" value="Digite sua tarefa" size="30" maxlength="50">
<a id="btn" class="button green large">+</a>
 
<ul id="tarefas" class="lista">
</ul>
</body>
</html>

E com isso você pode partir para exemplos mais sofisticados como um dataGrid por exemplo:

Veja abaixo

jquerytabela

Tem editar, selecionar tudo, soma de valores.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<link href="css/padrao.css" rel="stylesheet" type="text/css">
 
<script type="text/javascript">
 
 
 
	$(document).ready(function(e) {
		editable();
		disable();
 
 
 
		$("#checkAll").change(function(e) {
 
			 $("table td input").each(function(index, element) {
 
								if($("#checkAll").is(':checked')){
									$(element).attr("checked",true);
								}
								else{
									$(element).attr("checked",false);
								}
							///	alert($(element).val());
 
					});
        });
 
		var count = 1;
		$("#addMaisButton").click(function(e) {
			if(count == 1){
  			$("table").append('<tr class="d1"><td><input class="checkbox" type="checkbox"></td><td></td><td></td></tr>');
			count++;
			}else if(count == 2)
			{
				$("table").append('<tr class="d2"><td><input class="checkbox" type="checkbox"></td><td></td><td></td></tr>');
				count--;
			}
			editable();
        });
 
    });
 
	function disable()
	{
			$("table tr td:first-child").each(function(index, element) {
                	$(element).unbind('dblclick');
					$(element).unbind('keyup');
					$(element).unbind('focusout');
            });
 
	}
	function editable(e)
	{
		$("table tr td").each(function(index, element) {
 
				$(element).bind("dblclick",function edit(){
					$(element).html('<input class="input" type="text" value="'+$(element).text()+'" size="30" maxlength="50">');
					$('input').bind('focus',function focusEdit(){this.select()});
				});
 
				$(element).bind("keyup",
						function closeEdit(e){
							if(e.keyCode == 13){
							$(element).text($(element).find('input').val());
							somarTotal();
							}
				});
            });
 
	}
 
	function somarTotal()
	{
			var somageral = 0;
			$("table tr td:nth-child(3)").each(function(index, element) {
					//	somageral += ;
						if(!isNaN(parseInt($(element).text()))){
							somageral += parseInt($(element).text());
							//alert($(element).text());
						}
 
            });
			//alert(total);
		$(".total").text(somageral + ',00');
	}
</script>
</head>
 
<body>
<a class="button green large" id="addMaisButton">Adicionar +</a>
<table class="grid" width="650" border="0" cellpadding="10">
  <tr>
    <th width="26" scope="col">
      <input name="checkAll" type="checkbox" class="checkbox" id="checkAll"></th>
    <th width="340" scope="col">Descrição dos itens</th>
    <th width="184" scope="col">Valor</th>
  </tr>
  <tr class="d1">
    <td class=""> <input name="checkAll1" type="checkbox" class="checkbox" id="checkAll1"></td>
    <td>q</td>
    <td>10</td>
  </tr>
  <tr class="d2">
    <td class=""><input class="checkbox" type="checkbox" name="checkAll2" id="checkAll2"></td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr class="d1">
    <td class=""><input class="checkbox" type="checkbox" name="checkAll3" id="checkAll3"></td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr class="d2">
    <td class=""><input class="checkbox" type="checkbox" name="checkAll4" id="checkAll4"></td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>
<p>&nbsp;</p>
<p>Soma Total:R$<span class="total"></span></p>
</body>
</html>

Estude o código e veja como fiz, eu gastei uma média de 4 horas para fazer isso. Embora o código não esteja optimizado.

Abraços e até o próximo.

Flex/ JQuery

Redescobrindo o gosto pelos padrões Web : JQuery para devs Flex – Parte 3

Continuando com a série de posts sobre JQuery para desenvolvedores Flex, começo com um tema bem pertinente, formulários, já que é o calcanhar de aquiles de qualquer sistema que trafegue ou manipule dados.

Formulários

Dar-se com formulários é um caso muito sempre discutido em todas as instancias de linguagens de programação, seja ela para Desktop ou Web. Ninguém concorda com a API e acaba criando alguns mecanismos extras.

Não é diferente no Flex e nem tampouco no JQuery. Existem coisas em ambas que umas deveriam ser implementadas, para ficar igual.

Os formulários no Flex estão indo muito bem nessa versão 4.x do SDK, já que estão sempre em constante evolução, coisa que nas versões 3.x era bem divertida e tinha complementos bases que ajudavam bastante.

No JQuery

Veja esse exemplo simples.

jquery_forms

Embora o JQuery seja um complemento de manipulação ao HTML e CSS, ele traz uma série de funções pré-dispostas que facilita bastante o trabalho nesse exato momento de enviar os dados.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<link href="css/padrao.css" rel="stylesheet" type="text/css">
<title>JQuery e formulários</title>
 
 
<script type="text/javascript">
 
	$(document).ready(function() {
 
			// pegar valores do form e jogar em um alert
 
			$("#enviar").click(function(e) {
                	pegarValores();
            });
 
    });
 
	function pegarValores(){
			var resposta = $("#meuform").serialize();
		return alert(resposta);
	}
</script>
 
</head>
 
 
<body>
	<form id="meuform" style="width:240px;">
    	<p>
    	  <label>Usuario</label>
    	  <input id="login" name="login" type="text" size="10" maxlength="10">
   	  </p>
    	<p>
    	  <label>Senha</label>
    	  <input id="senha" name="senha" type="password" size="10" maxlength="10">
  	  </p>
      <p>
      	<a id="enviar" class="medium button green">Entrar</a>
      </p>
    </form>
</body>
</html>

Incrivelmente simples, passo o #id do formulário e executo a função serialize(). É fantástico, com uma função simples eu consigo fazer isso. Se eu fosse fazer no Flex, eu teria que criar minha classe própria para isso.

O que o serialize() realmente faz, ele faz um loop no form, pega cada campo e seu label correspondente caso exista e traz para mim os valores formatados em queryString já prontinhos para usar em qualquer um de seus métodos para trafegar dados. Se eu quiser implementar mais posso usar o serializeArray(), e ele me retorna em Array a resposta.

No Flex
Então se você cria forms básicos no Flex você faria uma função para coletar aquelas informações e envia elas para um servidor via HTTPService, RemoteObject, WebServices ou DataServices.
Querendo ou não se você for partir para um framework MVC,MVP você usaria o mecanismo automático do framework para cuidar disso.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
 
	<fx:Script>
		<![CDATA[
			import com.riacycle.form.FormUtil;
 
			import mx.controls.Alert;
			protected function pegarValores(event:MouseEvent):void
			{
				// TODO Auto-generated method stub
				Alert.show(FormUtil.serialize(meuform));
			}
		]]>
	</fx:Script>
 
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
	<s:Form id="meuform" x="201" y="87" width="256" height="128">
		<s:FormItem label="Usuario">
			<s:TextInput maxChars="10"/>
		</s:FormItem>
		<s:FormItem label="Senha">
			<s:TextInput displayAsPassword="true" maxChars="10"/>
		</s:FormItem>
	</s:Form>
	<s:Button x="349" y="223" label="Entrar" click="pegarValores(event)"/>
 
</s:Application>

Claro, utilizando a seguinte classe, cedida gentilmente pela RIACycle.

////////////////////////////////////////////////////////////////////////////////
//
//  RIACYCLE INC. LTDA BRAZIL
//  Copyright 2011 RIACycle Inc. LTDA
//  All Rights Reserved.
//
//  NOTICE: RIACycle Inc. permits you to use, modify, and distribute this file
//  in accordance with the terms of the license agreement accompanying it.
//	Code Licensed by MPL http://www.opensource.org/licenses/MPL-1.1
//
// Author: Igor Costa
//
////////////////////////////////////////////////////////////////////////////////
 
package com.riacycle.form
{
	import mx.core.IVisualElement;
	import mx.core.IVisualElementContainer;
	import mx.core.UIComponent;
 
	import spark.components.Form;
 
	public class FormUtil
	{
		public function FormUtil()
		{
		}
		/**
		 * @public
		 * Retorna em QueryString os campos de um formulário padrão do flex
		 * @return String
		 * @see spark.components.Form
		 * */
		public static function serialize(value:Form):String
		{
 
			var query:String;
			for (var i:int = 0 ;i <= value.numElements-1;i++)
			{
				var item:IVisualElementContainer = value.getElementAt(i) as IVisualElementContainer;
 
				for (var j:int = 0; j<=item.numElements-1;j++)
				{
					var input:UIComponent = item.getElementAt(j) as UIComponent;
 
					if(i <= value.numElements-1)
						query += item['label'] + "=" + input['text'] +'&';
				}
			}
			return String(query).substr(4,query.length-5); // remove o label do Form para title e remove o ultimo &
		}
	}
}
Flex/ Flex 4/ Flex 4.5/ HTML 5/ JQuery

Redescobrindo o gosto pelos padrões Web : JQuery para devs Flex – Parte 2

Continuando com as minhas descobertas, descritas nesse post. Gostaria de comentar algumas comparações para desenvolvedores Flex que queiram aprender JQuery.

Alguns aspectos interessantes

Mudança de propriedade em tempo de execução (tempo real)

Flex: Facilmente no Flex você muda propriedades em tempo de execução, através de várias formas, com CSS(StyleManager), Skin, Skinnable Class, Reflection e Actionscript.
Imagine o código abaixo do Flex, onde você tem um Rect (Retangulo) e você quer mudar sua largura e altura depois de 4 segundos que a App disparou o CreationComplete.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="init(event)">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
 
	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;
 
			private var tempo:Timer;
 
 
			protected function init(event:FlexEvent):void
			{
				// TODO Auto-generated method stub
				tempo = new Timer(4000);
				tempo.addEventListener(TimerEvent.TIMER,executar);
				tempo.start();
			}
			private function executar(e:TimerEvent):void
			{
				alvo.width = 100;
				alvo.height = 100;
				tempo.stop();
			}
 
		]]>
	</fx:Script>
 
	<s:Rect id="alvo" x="109" y="53" width="200" height="200">
			<s:fill>
				<s:SolidColor color="#000000"/>
			</s:fill>
	</s:Rect>
</s:Application>

Basicamente a única coisa que você precisa é da classe Timer e 2 métodos para mudança.

JQuery: Se eu for fazer isso no JQuery, basicamente eu uso do JQuery só a facilidade de chegar até o objeto e usar o método .css para alterar as propriedades, o resto é puro Javascript, eu faria assim.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
<style type="text/css">#alvo { width:200px; height:200px; background:#000; position:relative; top:40px; left:140px;}</style>
 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
 $(document).ready(function(e) {
    // inicia o documento
 
	var tempo = setTimeout("mudarPropriedades()",4000);
});
function mudarPropriedades(){
			$("#alvo").css("width",100);
			$("#alvo").css("height",100);
}
</script>
</head>
<body>
		<div id="alvo"></div>
</body>
</html>

Fácil, não? Esse assunto acaba levando a outro assunto que é estilo.

Estilo CSS

Flex:Uma das grandes facilidades que o Flex 4.x, tem é seu novo esquema de CSS, que é baseado na especificação nova do CSS 3, que é justamente a inclusão de namespaces para facilitar a compatibilidade e não só isso, como também sub selectors, typed selectors e os media query para diferentes telas (Multi-screen). O que era uma enorme desvantagem nas versões anteriores 2.x e 3.x que ainda eram baseadas na especificação CSS 2, que diga-se de passagem não suportava tudo do CSS2.

Tanto que o negócio era tão ruim no Flex 2.x e 3.x que tinha-se espaço para o Flex Style Explorer, eu achava isso um salvador da pátria. Já que programmatic skin era uma coisa horrível de se fazer.

Graças aos com noção, isso foi banido do novo Flex 4.x SDK e a coisa agora está uma maravilha. Então baseando-se na nova. como eu estilizo meus componentes em Flex via CSS?

O código abaixo me gera isso ai.
button

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx">
	<fx:Style>
		@namespace s "library://ns.adobe.com/flex/spark";
		@namespace mx "library://ns.adobe.com/flex/mx";
 
		s|Button {
				chromeColor:#000000;
				fontSize:20;
				color:#ffffff;
		}
	</fx:Style>
 
	<s:Button x="100" y="200" width="149" height="46" label="Hello World"/>
</s:Application>

JQuery: Na verdade nem seria JQuery e sim, CSS3 padrão, já que o CSS é uma linguagem de estilos para o HTML, isso teria mais sentindo se eu aplicasse o CSS 3 em um documento HTML 5, que a compatibilidade é quase 100%. Então para aplicar como eu faria?

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Blogs Post</title>
 
<style type="text/css">
.Button, .Button:visited {
	zoom: 1; /* zoom and *display = ie7 hack for display:inline-block */
	*display: inline;
	vertical-align: baseline;
	margin: 0 2px;
	outline: none;
	cursor: pointer;
	text-align: center;
	text-decoration: none;
	font: 14px/100% Arial, Helvetica, sans-serif;
	padding: .5em 2em .55em;
	text-shadow: 0 1px 1px rgba(0,0,0,.3);
	-webkit-border-radius: .5em;
	-moz-border-radius: .5em;
	border-radius: .5em;
	-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
	-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
	box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.black {
	color: #d7d7d7;
	border: solid 1px #333;
	background: #333;
	background: -webkit-gradient(linear, left top, left bottom, from(#666), to(#000));
	background: -moz-linear-gradient(top,  #666,  #000);
	filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#666666', endColorstr='#000000');
}
</style>
 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
 $(document).ready(function(e) {
    // inicia o documento
 
	var tempo = setTimeout("mudarPropriedades()",4000);
});
function mudarPropriedades(){
			$("#alvo").css("width",100);
			$("#alvo").css("height",100);
}
</script>
</head>
 
</head>
<body>
	<a class="Button black">Hello World</a>
</body>
</html>

Veja que se você salvar esse html e executar, ele vai te trazer a mesma aparência arredondada de um button padrão do Flex, uma coisa que me deixou desconfortável nesse ponto, foi o fato de ter que fazer N hacks e filtros para funcionar igual como no Flex, depois caiu a ficha e eu lembrei que o Flex para tornar isso fácil, ele já pre-define isso, então estão equiparados. Porém é compatível a aparência, só que no CSS e HTML como a linguagem é diferente do Flex que é compilada e no HTML e CSS3 ela é interpretada pelo navegador, eis o motivo dessa discrepância de aparência entre navegadores e o real motivo para os hacks em CSS3.

Módulos e modularizar Apps

Flex: Módulos, você tem ModuleLoader, Module, e uma cacetada de técnicas e teorias para deixar sua app leve e rápida, é um assunto extenso e não me cabe colocar aqui todo o assunto em poucos paragráfos, o assunto para mais de manga.
Em fim, em resumo, se você quer deixar a App leve, você modulariza ela em swf separados e os carrega apenas quando for necessário. A técnica mais básica para fazer isso, seria assim:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx">
 
	<fx:Script>
		<![CDATA[
			protected function button1_clickHandler(event:MouseEvent):void
			{
				mdContainer.unloadModule();
				mdContainer.loadModule("moduloA.swf");
			}
 
			protected function button2_clickHandler(event:MouseEvent):void
			{
				mdContainer.unloadModule();
				mdContainer.loadModule("moduloB.swf");
			}
 
		]]>
	</fx:Script>
 
	<s:controlBarContent>
	<s:Button label="Carregar Modulo A" click="button1_clickHandler(event)"/>
	<s:Button label="Carregar Modulo B" click="button2_clickHandler(event)"/>
</s:controlBarContent>
	<s:ModuleLoader id="mdContainer" width="100%" height="100%" >
 
	</s:ModuleLoader>
</s:Application>

Você descarrega o módulo anterior caso exista e carrega o próximo. Fácil não?

JQuery: O JQuery traz a tona um funcionamento muito similar a API do Flash que é para Carregar coisas , a Classe Loader, que é uma subclass do LoaderInfo, assim como o ModuleLoader.

No JQuery ele faz esse processo através do método .load ().

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Blogs Post</title>
 
<style type="text/css">
#Menu {
		width:100%;
		height:40px;
		display:block;
		position:fixed;
}
.meusModulos{ position:absolute; margin-top:44px; width:500px; height:500px;background:#f4f4f4;}
 
.Button, .Button:visited {
	zoom: 1; /* zoom and *display = ie7 hack for display:inline-block */
	*display: inline;
	vertical-align: baseline;
	margin: 0 2px;
	outline: none;
	cursor: pointer;
	text-align: center;
	text-decoration: none;
	font: 14px/100% Arial, Helvetica, sans-serif;
	padding: .5em 2em .55em;
	text-shadow: 0 1px 1px rgba(0,0,0,.3);
	-webkit-border-radius: .5em;
	-moz-border-radius: .5em;
	border-radius: .5em;
	-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
	-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
	box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.black {
	color: #d7d7d7;
	border: solid 1px #333;
	background: #333;
	background: -webkit-gradient(linear, left top, left bottom, from(#666), to(#000));
	background: -moz-linear-gradient(top,  #666,  #000);
	filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#666666', endColorstr='#000000');
}
</style>
 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
 $(document).ready(function(e) {
    // inicia o documento
 
	$("#btnA").click(function(){
			$("#moduleLoaderHTML").load("moduloA.html");
	});
	$("#btnB").click(function(){
			$("#moduleLoaderHTML").load("moduloB.html");
	});
});
 
</script>
</head>
 
</head>
<body>
	<div id="Menu">
	<a class="Button black" id="btnA">Carregar Modulo A</a>
    <a class="Button black" id="btnB">Carregar Modulo B</a>
    </div>
 
    <div class="meusModulos" id="moduleLoaderHTML"></div>
</body>
</html>

Os módulos basicamente são iguais, então posto aqui só modulo A o modulo B tem o mesmo código.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style type="text/css">
#estilos {background:#000; height:100% !important}
h2 {color:#fff; size:40px;}
</style>
</head>
 
<body >
<div id="estilos">
<h2>Modulo A Carregado com sucesso!</h2>
</div>
</body>
</html>

Tem uma infinidade de funções no JQuery, HTML e CSS que me fascinam, acho que vou colocar por aqui. Até a parte 3.

HTML 5/ JQuery

Redescobrindo o gosto pelos padrões Web : JQuery para devs Flex

Cerca de 20 dias atrás eu decidi que chegou a hora de aprender outras tecnologias além do Flex. Para mim não há nada de novo no SDK que eu já não consiga fazer, aquele tesão que você tem quando dia-a-dia trabalha com um framework. Eu ainda continuarei firme e forte com o Flex, mais não me deixa de lado o fato de querer tentar coisas novas. É da natureza do ser humano ser curioso. Eu acredito que eu nasci com isso em um nível 2.

Uma das minhas facilidades é de aprender rápido, super rápido, levando em consideração algumas técnicas absorvidas ao longo desses 11 anos na área de desenvolvimento. E isso me fez aprender com um método simples, associação por absorção. É mais ou menos assim. Deixa eu ver se explico.

Eu faço assim; Imagine um método no Flex chamado createChildren, eu associo a 2 coisas ( Criar Porcos) e desfio 1 porca com 10 leitões. 10 Leitões correspondem a 10 possibilidades que o método createChildren do Flex pode me dá ( add UI, executar função, remover UI, disparar evento, invalidar métodos, aplicar estilos, nascer com propriedades, criar definições de skins em tempo de execução, sobrescrever).

Então se 1 método pode fazer tudo isso, eu consigo absorver não só seu funcionamento, como também onde e porque usa-lo. Essa é umas das razões pelas quais eu consigo aprender rápido um novo idioma, e pode ser usado para qualquer área.

Porém voltando ao post, já que viajamos demais, eu queria me redescobrir, achar novos desafios, e adicionar funções não existentes ao Flex SDK que podem existir em outros frameworks, padrões e etc.

Decidir correr o risco de tentar algo novo com JQuery, já que de acordo com minhas pesquisas ajudadas pelo Homer Simpson, ele é um framework Top de linha para desenvolvedores Javascript. E no final das contas ele, faz muita coisa que o Flex já faz. Quem é desenvolvedor Flex, com toda certeza vai notar algumas semelhanças.

De lá para cá, foram ótimas coisas, muito legal fazer isso funcionar em N navegadores, uma das coisas que também o Flex faz com excelência.

Então para enfatizar meu aprendizado e ajudar você, meu fiel leitor, juntei algumas informações equivalentes tanto no JQuery quanto no Flex.

Definição de Documentos:

No Flex, você cria um novo Aplicativo, criando um arquivo qualquer com extensão (.mxml), porém dentro com as delimitações de tag

No JQuery, você cria um novo arquivo (.html) e adiciona a dependência do JQuery que está na versão 1.6.2, dentro de seu arquivo HTML entre as delimitações do tag

A inclusão da dependência, vai de gosto, você pode fazer referência tanto do diretório do seu projeto para o arquivo .js do JQuery, como também linkar direto da biblioteca do Google, A diferença é que local, você consome 31kb de banda do seu servidor, toda vez que alguém abrir teu site. Já via Link do Google;

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
</script>
Você economiza a banda do servidor.
 
<strong>Completou o load</strong>
 
No Flex, ele é caracterizado por uma série de eventos que são disparados em ordem quando o swf é despejado na tela do cliente. que vai desde o pre-initialize até creationComplete.
 
 
No JQuery, você define esse comportamento apenas pelo ready, que é uma espécie de creationComplete do Flex.
 
<pre lang="php">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>igorcosta.com - Testes de JQuery</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
 
<script type="text/javascript">
<!--
 
 $(document).ready(function() {
 
 
});
-->
 
</script>
 
</head>
 
<body>
 
</body>
</html>

O Ready, significa dizer que o documento está pronto para você executar o que deseja dentro dele.

Identificação de Objetos e Componentes

Quando se programa em Flex, você faz a referência de componentes por id ou por associação à uma classe específica.

Geralmente você identifica um componente no Flex assim:

 
  <s:Button label="Teste" id="meuBtn" click="execHandler(event)"/>

Fica fácil chegar a tal objeto pela sua referência pública.

Já no JQuery, ele chega até o objeto igual no Flex, por um ID ou por associação de uma tag, ao invés de classe como é no Flex.

Porém a sintaxe dele é um pouco diferente do Flex, já que ele faz referência ao $ dollar e o # para chegar ao elemento, ele sempre faz o loop geral para encontrar o individo dentro do documento e executar a tarefa do click como mostrei abaixo. Essa parte você vai se perder um pouco quando estiver aprendendo, já que parenteses e colchetes juntos em handlers, você sempre faz separado no Flex e não closure Functions.

 
<script type="text/javascript">
<!--
 
 $(document).ready(function() {
 
	 $("#btnChamar").click (function(e) {
		 alert('Hello World');
	 });
});
-->
 
</script>

Comunicação de dados

No Flex temos os tags (HTTPServices,WebServices,RemoteObject,DataServices).

Digamos que você quer chamar um serviço HTTP.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<fx:Script>
		<![CDATA[
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
 
			protected function blogService_resultHandler(event:ResultEvent):void
			{
				// TODO Auto-generated method stub
 
			}
 
			protected function faultHandler(event:FaultEvent):void
			{
				// TODO Auto-generated method stub
 
			}
 
		]]>
	</fx:Script>
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
 
	<s:HTTPService id="blogService" url="arquivo.php" result="blogService_resultHandler(event)" fault="faultHandler(event)"/>
	<s:Button click="blogService.send()" label="Executar Serviço"/>
</s:Application>

No JQuery temos os métodos ($.post(),$.get(),$.ajax(),$.load(),$.param())

Todos os métodos do JQuery para comunicar com dados são fantásticos, cada um tem sua particularidade, e quando você tem um certo conhecimento no JQuery ou é acostumado com o Flex, você vai acabar utilizando apenas o $.ajax(), já que é o único método que controla, eventos, cache e por ai vai.

No Flex para você pegar um resultado no PHP por exemplo que retorne um JSON, você teria que fazer.

Além de que você teria que usar alguma biblioteca JSON como (as3json ou as3corelib) para dar o parse do JSON.

No JQuery para você fazer isso, é hiper simples também.

<script type="text/javascript">
<!--
 
 $(document).ready(function() {
 
	 $("#btnChamar").click (function(e) {
 
				$.ajax({
					url: "recursos.php",
					type: "GET",
					dataType:'json', // aceita html,json,xml,script
					success: function (data){
						$("#resposta").html(data.paragrafo);
 
					},
					error: function (data){
						alert(data);
					}
 
					});
	 });
});
-->
 
</script>
 
</head>
 
<body>
 
<a id="btnChamar" href="#chamar-servico">Executar tarefa</a>
	<p id="resposta"></p>
</body>

Eu estou requisitando essa página simples de PHP que me retorna um JSON.

<?php
 
$retorno = array();
 
 
$retorno['paragrafo'] = "Gooollll, conseguimos!";
 
 
echo json_encode($retorno);

Documentação

Ninguém pode negar que a documentação do Flex é bem completa, detalha muitas classes e quase algumas são esquecidas propositalmente, porém a documentação é hiper vasta.

No JQuery, a documentação dele também é completa, e semelhante ao Flex, com integração de comentários em cada página, que é meio que um padrão no mundo web, já que muita gente implementa de maneira diferente a mesma coisa, e acaba que essas implementações vão te ajudando a solucionar problemas.

Efeitos

Umas das grandes qualidades do Flex que eu considero bastante, são os efeitos, sinceramente muita coisa foi herdada das classes Tween de Robert Penner, e as mais recentes mudanças com o atual extinto do Flex SDK Chet Haase(Atualmente trabalhando no Google SDK), fez nas animações, e muita coisa hiper bacana como 3D, reverse, reuse, pause, cache e por ai vai.

Os efeitos são básicos, mais tem gente que anda por ai fazendo muito mais, já que existem Zilhões de plug-ins para o JQuery. 3D por exemplo.

Um exemplo prático, estou usando o efeito Flip, um plug-in já criado para isso, criado por Luca Manno.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>igorcosta.com - Testes de JQuery</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="jquery.flip.min.js"></script>
 
<script type="text/javascript">
<!--
 
 $(document).ready(function() {
 
	 $("#meuBloco").click (function(e) {
 
			$("#meuBloco").flip({
				direction:'lr', // esquerda para direita
				color:'#aa0000' // cor final do flip
			})
 
	 });
});
-->
 
</script>
<style>
		#meuBloco { width:120px; height:120px;background:#F90; margin-left:220px; margin-top:100px; position:relative;}
</style>
 
</head>
 
<body>
 
    <div id="meuBloco"></div>
</body>
</html>

Adicionando Elementos em tempo de execução

Outra facilidade tremenda do Flex é a adição e subtração de itens da tela, o que agente chama de “em tempo de execução”.

Para fazer isso no Flex de maneira fácil, você geralmente faz:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
 
		<s:layout>
			<s:BasicLayout/>
		</s:layout>
 
	<fx:Script>
		<![CDATA[
			protected function addHandler(event:MouseEvent):void
			{
				var novo:Button = new Button();
				novo.label = "Botao " + Math.random()*1000;
				comps.addElement(novo);
 
			}
		]]>
	</fx:Script>
 
	<s:Button label="Add Componente" click="addHandler(event)" />
	<s:Group id="comps">
			<s:layout>
				<s:VerticalLayout/>
			</s:layout>
	</s:Group>
</s:Application>

No JQuery, é também simples, veja um exemplo.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>igorcosta.com - Testes de JQuery</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="jquery.flip.min.js"></script>
 
<script type="text/javascript">
<!--
 
 $(document).ready(function() {
 
	 $("#add").click (function(e) {
 
			$("#lista").append("<li>Elemento</li>");
	 });
});
-->
 
</script>
<style>
		ul { list-style:none; width:100px; }
		ul li { background:#000; color:#fff; margin-top:5px; margin-bottom:5px;}
</style>
 
</head>
 
<body>
		<a id="add" href="#adicionando">Adicionar Itens</a>
        <ul id="lista">
        </ul>
</body>
</html>

Ao longo de alguns posts, vou falando mais sobre as descobertas que fiz, se eu fosse você começava também a explorar novos mundos. Aguardem a parte 2.

JQuery

JQuery Brasil

Ultimamente eu tenho gastado meu tempo livre estudando JQuery. Por tanta gente falar e ver tendencias da O’Reilly como um framework que sempre fica ali logo abaixo do Flex para plataforma RIA. Decidir estudar e já tenho vários exemplos feitos locais aqui que quem sabe um dia compartilho com vocês como sempre fiz.

Agora é a vez de participar de uma comunidade, e acabei achando uma comunidade já existente chamada JQuery BR, lá no Google Groups que embora tenha pouca atividade tem tópicos bem quentes que me ajudam sempre que pinta aquila dúvida.

É muito dificil para quem está acostumado com o DOM do Flex mudar para o DOM de um Javascript da vida e sair programando a tortas e direitas. Porém nada é impossível.

Vale a pena a todos pelo menos ler o conteúdo da lista ao invés de participar.