Evento body onReady sem o uso de libs (DOM)

Posted by micox at Novembro 13th, 2007

Aberta novamente a temporada de postagens heheh.
Um serviço que eu estava fazendo maneirou e acho que posso voltar a ser mais periódico aqui no blog.

Bora lá com o on ready. Leia até o final :)

Bom, grande parte da malandragem que lê este blog usa frameworks e, portanto, devem conhecer as facilidades de uma função/evento on ready. Quem não conhece, vai achar esta postagem muito útil.

Perceba que não estou falando do onreadystate do AJAX nem do onready de iframes e afins, mas de onready no javascript. Continue lendo que entenderá.

Vou copiar aqui algumas descrições do que é o ‘on Ready’ pra não ter que ficar
definindo tudo novamente:

[…] Ready é semelhante ao onload do body, porém ele não
espera carregar imagens e objects, ou seja, assim que estiver carregado todo o HTML ela é executada! Muito útil! […] - jQuery Introdução - Felipe Diesel

[…]onReady é um método automaticamente chamado quando o DOM estiver completamente carregado, garantindo que todos os elementos referenciados na sua aplicação estarão disponíveis quando o script rodar. […] ( Introdução à bibliteca EXTjs - Fábio Vedovelli )

Nós usamos constantemente o ‘window.onload’ ou o ‘body.onload’ pra dizer que devemos iniciar a execução do nosso script. Porém, o evento onload espera tooooooda a tonelada de imagens/objetos/etc serem carregados antes de ser disparado.
Carambola, na imensa maioria das vezes nós precisamos apenas que os elementos HTML estejam carregados. É isso que o on ready faz! Que legal, dãã!

Em muitas bibliotecas este evento já está incluso (EXTjs e jQuery por exemplo), porém quem não usa bibliotecas ou cujas bibliotecas não tem o onready ficam a ver navios.
Tadáaaa: o Mico tem a solução!

“Chega de papo mico, você nunca foi de papo. Mostra logo um exemplo e o maldito script pra onload pra quem não usa bibliotecas.”

<script>
//vai funcionar rapidão pois não precisa esperar a imagem, só o carregamento do HTML
bodyOnReady(function(){
	alert('bodyOnReady ' + document.getElementById('teste').innerHTML)
})

//vai funcionar beleza, mas só depois que tooodos os elementos forem carregados
window.onload = function(){
	alert('onload ' + document.getElementById('teste').innerHTML)
}

//vai dar erro pois o elemento 'teste' ainda não foi criado
	alert('alert simples ' + document.getElementById('teste').innerHTML)

</script>
<body>
<img src='http://img119.imageshack.us/img119/4050/no20matinhoue1.jpg' alt='imagem (relativamente) grande' />
<div id='teste'>conteúdo da div</div>
</body>

Entenderam a parada aí? Pois é.

“Mas cadê a função bodyOnReady Mico? A parada aí não funcionou pois tá faltando a função bodyOnReady” - Calma, está abaixo. É só adicioná-la em seu script e usar conforme a sintaxe passada no exemplo acima.

function bodyOnReady(func){
 //call the function 'func' when DOM loaded
 //Version 2.0 - 03/03/2008 - based on Jquery bindReady
 //by Micox - www.elmicox.com - elmicox.blogspot.com - webly.com.br
 //http://www.elmicox.com/2007/evento-body-onready-sem-o-uso-de-libs/

 if(document.addEventListener && navigator.appName.indexOf('Opera')<0){ //FF
	document.addEventListener( "DOMContentLoaded", func, false );

 }else if(navigator.appName.indexOf('Internet Explorer')>=0){ //IE
	try { // by Diego Perini - http://javascript.nwbox.com/IEContentLoaded/
		document.documentElement.doScroll("left");
		func();
	} catch( error ) {
		setTimeout( arguments.callee, 20 );
		return
	}

 }else if(navigator.appName.indexOf('Opera')>=0){
	document.addEventListener( "DOMContentLoaded", function () {
		for (var i = 0; i < document.styleSheets.length; i++){
			if (document.styleSheets[i].disabled) {
				setTimeout( arguments.callee, 0 );
				return;
			}
		}
		func();
	}, false);
 }

}

Várias tentativas de fazer o onready também estão disponíveis na net se
quiserem testar. Esta aqui é só a minha versão (meio gambiarra pra variar).

Só testei no IE6, FF2 e OP9 e em poucas situações. Em caso de bug, não esqueçam de me avisar. Em caso de melhorias, manda ae.

Posted in DOM, funções, javascript| 8 Comments | 

Javascript DOM Inspector para IE - colaboradores

Posted by micox at Setembro 20th, 2007

Javascript DOM Inspector para IE - em busca de colaboradores.

Comecei a brincar de fazer um DOM explorer usando javascript.
Motivo? Fazer um dom explorer pra ajudar agente a resolver os boró no Internet Explorer e Opera (afinal já temos o ótimo firebug no FF que não precisa de substitutos).

Tentando desenvolver um aqui. Ajude também se vc sacar de javascript.

Eu dei os começo mas vou dar uma parada pra ir agilizando meus serviços.

Acredito que será útil pra quem desenvolve muito com javascript.

Posted in DOM, bate-papo, javascript| No Comments | 

Include em JavaScript

Posted by admin at Fevereiro 6th, 2007

Olá povo.

Uma coisa de JavaScript um pouco incomum, que aparentemente ninguém possa
ter precisado, mas que deve fazer muita falta para programadores que vêm de
outras linguagens: um include em JavaScript.

"Bah, que isso mico, é só eu escrever a tag script e dizer o arquivo que quero chamar no head do HTML".

Sim, malandro, mas se você tiver vários arquivos javascript e não quiser incluir todos de uma vez?
Se você precisar incluir algum só se alguma determinada condição for feita?

Por exemplo

if(sou_bonito==true)  {
 include("chama_mulher.js");
} else if(tenho_grana==true) {
 include("chama_mais_mulher.js");
}else if(sou_inteligente==true){
 include("vai_trabalhar_vagabundo.js");
}

"Perae macaco doido. Comé que você vai fazer isso com JavaScript?"

Elementer meu caro leitor:

function include(arquivo){
//By Fabrício Magri e Micox
//http://elmicox.blogspot.com/2006/12/include-em-javascript.html
 var novo = document.createElement('script');
 novo.setAttribute('type', 'text/javascript');
 novo.setAttribute('src', arquivo);
 document.getElementsByTagName('head')[0].appendChild(novo);
 //apos a linha acima o navegador inicia o carregamento do arquivo
 //portanto aguarde um pouco até o navegador baixá-lo. :) }

Infelizmente, pra variar, o meu Opera 8.5 não gostou deste script. Mas é a vida… No IE 6.0 e no FF 2.0 deu tudo beleza.
Graças ao comentário de um anônimo Fabrício Magri o script funfou no Opera 8.5 (vejam os comentários), muito obrigado :). Agora funciona corretamente no FF, IE e OP.

Bugs, dúvidas, sugestões é só comentar aí. Comenta pra eu escrever mais.

Amanhã tem mais postagem. Agora tô com pressa. Até lá.

Posted in DOM, javascript| 1 Comment | 

InnerHTML em Select Option

Posted by admin at Janeiro 29th, 2007

Opa.

Seguindo uma postagem do Julio Greff sobre o velho problema (bug) do IE ao trabalhar com innerHTML e a tag select, vou mostrar aqui minha solução que eu já tinha feito na época da minha função simples pra ajax.

Pequena explicação do problema: às vezes, é necessário agente preencher uma tag select com options através de innerHTML. Pra variar, o IE dá problema com isso. Tá certo que innerHTML não é uma propriedade DOM padrão, mas se o Internet Explorer decidiu implementar ela, deveria, pelo menos, ter implementado direito hehe. Bah, deixa de reclamação mico.

Exemplo:

document.getElementById("meu_select").innerHTML = "<option value='1'>não</option> <option value='2'>funfa</option>"; 

O script acima deveria colocar dentro da select chamada "meu_select" duas opções ("não" e "funfa"). Só que isso não funfa no IE. O jeito certo então é adicionar através de appendChild!!!

Mas, calma, não se desespere, não será necessário você ficar quebrando a cabeça com infinitos appendChild. O Mico resolveu o problema pra você. Basta adicionar minha função abaixo no seu script e chamá-la passando 2 parâmetros: o ID do select que você quer preencher e o innerHTML que você quer colocar dentro deste select.

A função vai cuidar de tudo, como se você estivesse setando através da propriedade innerHTML mesmo, inclusive os atributos do option.

Exemplo de uso (baseado no exemplo anterior que não funfava):

var inner = "<option value='1'>Agora</option> <option value='2'>funfa</option>"; 
select_innerHTML(document.getElementById("meu_select"),inner);

A função mágica que faz isso. Adicione copie no seu script:

function select_innerHTML(objeto,innerHTML){
/******
* select_innerHTML - altera o innerHTML de um select independente se é FF ou IE
* Corrige o problema de não ser possível usar o innerHTML no IE corretamente
* Veja o problema em: http://support.microsoft.com/default.aspx?scid=kb;en-us;276228
* Use a vontade mas coloque meu nome nos créditos. Dúvidas, me mande um email.
* Versão: 1.0 - 06/04/2006
* Autor: Micox - Náiron José C. Guimarães - micoxjcg@yahoo.com.br
* Parametros:
* objeto(tipo object): o select a ser alterado
* innerHTML(tipo string): o novo valor do innerHTML
*******/
    objeto.innerHTML = ""
    var selTemp = document.createElement("micoxselect")
    var opt;
    selTemp.id="micoxselect1"
    document.body.appendChild(selTemp)
    selTemp = document.getElementById("micoxselect1")
    selTemp.style.display="none"
    if(innerHTML.toLowerCase().indexOf("<option")<0){//se não é option eu converto
        innerHTML = "<option>" + innerHTML + "</option>"
    }
    innerHTML = innerHTML.replace(/<option/g,"<span").replace(/<\/option/g,"</span")
    selTemp.innerHTML = innerHTML
    for(var i=0;i<selTemp.childNodes.length;i++){
        if(selTemp.childNodes[i].tagName){
            opt = document.createElement("OPTION")
            for(var j=0;j<selTemp.childNodes[i].attributes.length;j++){
                opt.setAttributeNode(selTemp.childNodes[i].attributes[j].cloneNode(true))
            }
            opt.value = selTemp.childNodes[i].getAttribute("value")
            opt.text = selTemp.childNodes[i].innerHTML
            if(document.all){ //IEca
                objeto.add(opt)
            }else{
                objeto.appendChild(opt)
            }
        }
    }
    document.body.removeChild(selTemp)
    selTemp = null
}

Bugs? Grita nos comments ae. Dúvidas? Joga no fórum e me avisa.
Não se esqueça de conferir também a solução do Julio para este problema.

Posted in DOM, javascript| 1 Comment |