sábado, 16 de agosto de 2008

Capturando valores Css dos objetos.

Já tentaram recuperar algum valor do Css de objetos onde não foi atribuído o estilo pelo Js e nem foi atribuído em in-line?

Vou explicar melhor:

div#box{
width:100px;
height:100px;
border:1px solid red;
}

<div id="box"></div>


O que aconteceria se eu fizesse:


alert( document.getElementById("box").style.height )


???

O retorno seria :"".

Duas formas rápidas de se resolver isso seria usar Css in-line, setando diretamente na tag o valor do “height”, ou setar o valor inicialmente com javascript.

As duas formas são ruins, pra falar a verdade. Existe uma forma de pegar esses valores com javascript e pra variar temos dois js, um para navegadores e outro para o iE.

Para os navegadores:


document.defaultView.getComputedStyle(elemento, null).getPropertyValue()


Para o iE:


Elemento.currentStyle


Bom, pelo menos o código do iE é bem mais elegante.

Eu já havia postado sobre isso e uma possível solução no fórum.
Mas não apareceu ninguém para fazer alguma crítica ( construtiva ) sobre meu algoritmo.

Que era esse:


function $style(elem, att){
if(elem.currentStyle) return (elem.currentStyle[att])
return document.defaultView.getComputedStyle(elem, null).getPropertyValue(att)
}


Porém ela pode ser melhorada, e percebi isso lendo um dos meus blogs favoritos que é o Milfont. O Milfont nesse post falou sobre o design pattern Bridge para encapsular o X-Browser.

O problema do meu algoritmo é que toda vez que a função $style fosse chamada, ela precisaria testar qual navegador eu estou usando. Nesse caso, o script tem 5 linhas e não há perda de desempenho significante, porém, vamos já nos acostumar a fazer da forma mais correta desde já.

Seguindo a lógica que Milfont descreveu, o algoritmo poderia ser melhorado para este formato:


var currentStyle = new function X(){
if(document.all)
return function(el, att){ return el.currentStyle[att] }

return (
function(el, att){
return document.defaultView.getComputedStyle(el, null).getPropertyValue(att)
}
)
}


Pronto, agora ao chamar currentStyle os navegadores estariam usando o document.defaultView. Já os iE´s da vida usariam o element.currentStyle.


var box = document.getElementById("box")
alert( currentStyle( box, "height" ) )


É isso aí, abraços.

sábado, 9 de agosto de 2008

Bordas arredondadas ( Rounded Corners )

Olá de novo.

Esses dias me vi na necessidade de usar uma caixa com borda arredondada e pensei em uma maneira de fazê-la, queria compartilhar com vocês.

Para montá-la eu usei uma miniaturização da estrutura de layout padrão de sites. Um header, dentro dele duas bordas esquerda e direita, o conteúdo central e o footer com bordas esquerda e direita.

As bordas estão dentro do header e do footer. Pensei em fazer as bordas, o header e o footer com span e o conteúdo com div.

Ficou assim o Html:

<div class="rounded">
<span class="r-header">
<span class="top-left"></span>
<span class="top-right"></span>
</span>

<div class="r-content"></div>

<span class="r-footer">
<span class="bottom-left"></span>
<span class="bottom-right"></span>
</span>
</div>


E o Css:



.rounded{ display:table; width:20% }
.r-header,
.r-footer,
.r-content { display:block; clear:both }

.top-left,
.top-right,
.bottom-left,
.bottom-right {
display:block;
line-height:0px;
width:6px; height:24px;
}

.top-left, .bottom-left{ float:left }
.top-right, .bottom-right{ float:right }

.r-header, .r-footer{ height:24px; background-repeat:repeat-x }

.top-left{ background:url(left-top.gif) no-repeat }
.r-header{ background-image:url(back-top.png) }
.top-right{ background:url(right-top.gif) no-repeat }

.bottom-left{ background:url(left-bottom.gif) no-repeat }
.r-footer{ background-image:url(back-bottom.png) }
.bottom-right{ background:url(right-bottom.gif) no-repeat }
.r-content{border:1px solid silver ; height:auto; }


Claro, fazendo com classes pois se quisesse montar várias caixas desta numa página, ficaria no mínimo trabalhoso ficar replicando várias id´s. Burrice.

Mas, melhor ainda seria se eu não precisasse inserir o mesmo html toda hora pra cada elemento com borda arredondada. Então, entra o Js:



function rounded(css, context){
var t = context? context.getElementsByTagName("*"):document.getElementsByTagName("*")

for(var x=0; x<t.length; x++)
if(t[x].className && t[x].className.match(/rounded/)){
var temp = t[x].innerHTML

var content = '<span class="r-header"><span class="top-left"></span><span class="top-right"></span></span>'
content += '<div class="r-content">'+ temp +'</div>'
content += '<span class="r-footer"><span class="bottom-left"></span><span class="bottom-right"></span></span>'

t[x].innerHTML = content
}

var link = document.createElement("link")
link.rel = "stylesheet"
link.type = "text/css"
link.href = css

document.getElementsByTagName("head")[0].appendChild(link)
}



Como funciona, rounded recebe 2 parâmetros, o segundo é o escopo de onde deseja procurar seus elementos, se não passar o segundo parâmetro a função procura no documento todo objetos que tenham a classe "rounded". O primeiro parâmetro é a localização do Css que usou para formatar as bordas arredondadas.

Eu particularmente prefiri fazer o Css separado neste caso, porque era necessário o scripttag para atualizar as caixas no FF.

Achando os elementos ele pegará cada um deles e fará cópia de seu conteúdo, posteriormente atualiza o conteúdo colocando as tags html necessárias para formatar a caixa arredondada concatenado com o conteúdo antigo. Bem simples. Há formas mais rápidas e melhores de se fazer um script desse, mas isso é pra mais tarde =)

Ou seja, se usar a classe "rounded" em um form, o conteúdo do form será guardado, neste form serão colocadas as tags span contendo as bordas junto com uma div de classe "r-content" contendo todo o conteúdo antigo do formulário.

Se o Js não for carregado ou se o browser do usuário não permitir Js, a página será exibida corretamente, porém sem as estilizações.

Veja um exemplo do código funcionando aqui.

Legal né? Mas o grande lance é saber fazer a caixa de modo que possa reaproveitá-la, ou seja, pode aumentar o tamanho dela ou diminuir, ela deve ficar bem renderizada, certinha. Depois se precisar redimensionar, alterar as bordas ou formatar uma caixa específica, basta adicionar um id pra ela no seu Css.

É isso, abraço.

Quem sou eu

São Paulo, São Paulo, Brazil
Sou estudante de Ciência da Computação e acabei virando nerd por acidente. Em meados de 1998/1999 meu interesse era mais jogar futebol, odiava computador. Mas eu acho que caí algum dia no treino e bati a cabeça... tsc tsc. Pior para o mundo do futebol...