Ver Mensaje Individual
  #15 (permalink)  
Antiguo 21/12/2007, 15:03
furoya
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 21 años, 5 meses
Puntos: 317
Re: Texto en dos columnas

De nada, derkenuke. Es indudable que te gusta destripar códigos. Pero que éste sea una vergüenza, y que le salten bichos por todos lados ya te quita las ganas de mirarlo.

Con una pasada ya me di cuenta por qué lo sacaron de línea en cuanto lo probaron en otros navegadores que no eran IE.

Vamos a retomar un poco el tema desde el principio. Lo que desde ya tiene que quedar claro es que no podemos hacer 2 ó más columnas en JS. Eso lo tiene que hacer el navegador; lo más a que podemos aspirar es a una simulación llena de limitaciones. Y la que elijamos hacer será la que mejor se adapte a cada proyecto.

Un texto a 2 columnas está dentro de un mismo bloque, sólo se corta visualmente y eso permite mantener formatos, enlaces y demás sin modificar el documento.
Nosotros tendremos que dividirlo y meter cada columna en un bloque distinto, lo que destruye el documento y -como mínimo- le quita accesibilidad.

Firefox ya las tiene, y se llaman desde el CSS; así que no nos vamos a ocupar de él.

Otro problema es decidir qué hacemos si al dividir en 2 nos quedan columnas de mayor altura que la de la ventana. Porque si tenemos que usar scrollbars las columnas carecen de sentido.

Ahora empecemos. Creo que hay 3 maneras de simular estas columnas.

En IE existe -como ya mencioné y puse ejemplo- getClientRects(); que nos permite no sólo contar las líneas, sino saber donde empiezan o terminan en altura, y nos deja usar caracteres de distinto tamaño. Así, en vez de "cortar" párrafos para pasar a otro bloque, lo que haremos es duplicar el contenido en cada bloque, medir hasta la línea de "la mitad", darle a esa columna esa altura y desplazar el contenido de la segunda la misma altura, hacia arriba.

Pero como no funcionan en otros navegadores, vamos a usar el "truco" del código de LN : le damos una medida absoluta a la fuente y la usamos para todo el texto.

Código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<title>DIVIDE TEXTO.</title>
<script type="text/javascript">

var unidad, cont1, alturaCol, semiAltCol, lineasCol;
var muestra = 1;

function inicio(){
document.getElementById("col1").style.width = "300px";
unidad = parseInt(document.getElementById("unid").offsetHeight);
cont1 = document.getElementById("col1").innerHTML;
alturaCol = parseInt(document.getElementById("col1").offsetHeight);
lineasCol = alturaCol / unidad;
semiAltCol = (Math.ceil(lineasCol / 2)) * unidad;

if(muestra == 1){columnaD();} else{columnaS();}
}

function columnaD(){
document.getElementById("pag").style.height = semiAltCol + 20 +"px";
document.getElementById("col2").style.display = "block";
document.getElementById("contCol2").innerHTML = cont1;
document.getElementById("col1").style.height = document.getElementById("col2").style.height = semiAltCol +"px";
document.getElementById("col1").style.width = "300px";
document.getElementById("contCol2").style.marginTop = "-"+ semiAltCol +"px";
}

function columnaS(){
document.getElementById("col2").style.display = "none";
document.getElementById("col1").style.height = "auto";
document.getElementById("col1").style.width = "610px";
document.getElementById("pag").style.height = parseInt(document.getElementById("col1").offsetHeight) + 20 +"px";
}

function cambia(){
if(document.getElementById("col2").style.display == "block" ){
document.getElementById("pag").title = "Dos columnas / Ajusta al tamaño.";
muestra = 2;
}
else{
document.getElementById("pag").title = "Una columna / Ajusta al tamaño.";
muestra = 1;
}
inicio();
}

onload = inicio;
</script>

<style type="text/css">
body{background-color : black; color : white; font : 100%/125% arial, helvetica, sans-serif; }
#unid , #col1 , #col2 {font: 90%/125% arial, helvetica, sans-serif; position: absolute; }
#col1 , #col2 {width: 300px; height: auto; overflow: hidden; top: 10px; left: 10px; background-color: white; color: black; text-align:justify; /*text-justify : auto;*/ }
#col2 {top: 10px; left: 320px;}
#pag {position: relative; height: auto; width:630px; background-color: silver; cursor : hand;}
#pag {cursor : pointer;}
span{background-color : red; font-weight : bold;}
h2 , p{font-family : "times new roman", times, georgia, serif;}
</style>
</head>
<body>
<div id="unid">.</div>
<h2>Muestra el texto en una o dos columnas.</h2>

<div id="pag" onmousedown="cambia()" title="una columna"><div id="col1">
01 yctrbqweu crtbqweui tyr ctyw yjhuety tyeiqeru tyor poetuv .<br>
02 uiowcty eqrouo yp qeotvuiqe oiueq poiueqp uyv uy ewripo pewqroiu`p968 v'6 .<br>
03 568091u4 26 po.<br>
04 yctrbqweu crtbqweui tyr cbyqdar rt tyiqeru tyor poetuv .<br>
05 yctrbqweu crtbqweui tyr ctyiqeru tyor poetuv.<br>
06 uiowcty eqrouo yp qeotvuiqe oiueq poiueqp uyv uy ewripo pewqroiu`p968 v'6.<br>
07 568091u4 26 po.<br>
08 yctrbqweu crtbqweui tyr ctyiqeru tyor poetuv.<br>
09 uiowcty eqrouo yp qeotvuiqe oiueq poiueqp uyv uy ewripo pewqroiu`p968 v'6.<br>
10 568091u4 26 po.<br><span>
11 yctrbqweu crtbqrs tybwvwrweui tyr ctyiqeru tyor poetuv.<br>
12 yctrbqweu crtbqweui tyr ctyiqeru tyor poetuv.<br>
13 uiowcty eqrouo yp qeotvuiqe oiueq poiueqp uyv uy ewripo pewqroiu`p968 v'6</span>.<br>
14 568091u4 26 po.<br>
15 yctrbqweu crtbqweui tyr ctyiqeru tyor poetuv .<br>
16 yctrbqweu crtbqweui tyr ctyiqwvbywreru tyor poetuv.<br>
17 uiowcty eqrouo yp qeotvuiqe oiueq poiueqp uyv uy ewripo pewqroiu`p968 v'6.<br>
18 568091u4 26 po.<br>
19 yctrbqweu crtbqwbyrwr ybutey weui tyr ctyiqeru tyor poetuv.<br>
20yctrbqweu crtbqweui tyr ctyiqeru tyor poetuv.<br>
21 uiowcty eqrouo yp qeotvuiqe oiueq poiueqp uyv uy ewripo pewqroiu`p968 v'6.<br>
22 568091u4 26 po.<br>
</div>

<div id="col2"><div id="contCol2"></div></div>
</div>

<p>Al cambiar el tama&ntilde;o de fuente se debe ajustar la/s columna/s con click.</p>
</body>
</html>
La ventaja es que muestra los formatos. La desventaja es que su lectura será desastrosa para navegadores de voz y quizá para impresión. Y no se puede aumentar el tamaño de texto*.

Otro método es el que enlacé arriba. Se corta el texto en cadenas de 1 párrafo c/u y se rellenan las columnas. Cuando llegamos al "medio", cortamos ese párrafo en palabras y las vamos distribuyendo mientras las alturas se mantengan o aumente la primera, que puede ser 'una línea más alta' que la segunda.
Por supuesto, no puede haber etiquetas de formato, porque es complicado cortarles el texto, y al igual que en el ejemplo anterior, un id no se puede duplicar.

Por último ... creo que nos estamos ahogando en un vaso de agua. Lo difícil es medir el contenido de una columna para meterlo en dos; pero es mucho más fácil hacer 2 columnas y después juntar el contenido en 1. Para volver a las 2, simplemente reescribimos el documento original o recargamos. Así no ahorramos el escript que hace todos los cálculos por nosotros.

Y por supuesto, tampoco se puede cambiar la medida del texto cuando esté a 2 columnas.

Espero que alguna de estas ideas sirva para algo.

Y virla, no traigas más porquerías.

[edit]
* Me quedé pensando en el tamaño de texto. Como habrán visto en el ejemplo, la altura de cada línea se saca de un caracter y no del CSS, porque la idea era que se leyera dinamicamente. Corregí el código para usar -ahora sí- medidas relativas, pero no encontré un evento que detecte cuándo usamos "Ver > Tamaño de texto", así que hay que cliquear cada vez que querramos ajustar las columnas.
Peor es nada.
[/edit]

Última edición por furoya; 23/12/2007 a las 07:08 Razón: mejorar el ejemplo