Voy a hacer una aportación más, no sé si será la última.
Este script es para IE también, me he despreocupado de FF por que ya tiene CSS propio. No cuento otros navegadores como Opera, que lo he probado y funcionar funciona, pero se descoloca todo bastante, se calculan mal las alturas...
Bueno, mi script se basa en coger cada palabra del texto dado, y meterla en un DIV. Es un poco lentorro, pero se puede soportar. Evidentemente el texto no puede ser demasiado largo... Una vez tenemos "encapsulada" cada palabra, podemos controlar dónde se encuentra, si empieza nueva línea, o si se sale del DIV que contiene la columna.
En IE no sale nada mal, la verdad, aunque el CSS está un poco ajustado. He comentado el script línea por línea para que todo el mundo lo pueda entender, a ver si avanzamos en ésto para los demás navegadores.
Código 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" xml:lang="es" lang="es">
<head>
<meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" />
<meta name="Author" content="derkeNuke" />
<title>Página nueva</title>
<style type="text/css">
body {
height:100%;
}
#elArticulo {
width: 58%;
background-color: #FFF4D2;
height: 80%;
font-size: 0.7em;
font-family: verdana;
margin:0;
padding:50px 10px 30px 20px;
line-height: 1.3em
}
#elArticulo p {
margin:0;
margin-bottom: 1.3em;
}
.pal {
display: inline;
}
.columnata {
clear: both;
width: 97%;
height: 700px;
}
.columna {
width: 48%;
padding: 3px;
background-color: #EDFFCC;
/*border: solid 1px #669900; */
height: 700px;
float:left;
}
</style>
</head>
<body>
<div id="elArticulo">
<p>TEXTO 1 -- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc malesuada, orci nec convallis elementum, justo dui sodales felis, eu ullamcorper ante risus a mi. Mauris at mauris. Ut et ipsum quis mi accumsan consectetuer. Donec dictum sem nec ante. Proin magna libero, elementum eget, scelerisque nec, consequat vitae, dui. Pellentesque malesuada mauris vel diam. Vestibulum a sem. Vivamus magna massa, ullamcorper ac, varius pretium, aliquet nec, arcu. Nam tempor accumsan nulla. Fusce ipsum. Quisque ac ipsum non nisi commodo tincidunt. Etiam turpis. Duis bibendum velit non nisl. Nam volutpat lacinia erat. Nunc euismod. Suspendisse vel dolor non arcu pellentesque ultrices.</p>
<p>Sed iaculis libero et nisl. Sed congue dui sit amet est. Morbi sit amet elit vel turpis varius tristique. Morbi ac mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean sit amet nibh sed turpis nonummy euismod. Maecenas magna. Etiam suscipit, urna vitae sodales euismod, diam orci mollis libero, at pulvinar arcu sapien sit amet lectus. Nunc sagittis lobortis mi. Quisque ultrices.</p>
<p>In sem. Sed suscipit ipsum at mauris. Ut aliquam orci ullamcorper ligula. Nam sed arcu et nulla volutpat egestas. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Suspendisse rhoncus. Suspendisse venenatis sapien vitae lorem. Mauris porta quam non nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque quam justo, dapibus sed, ullamcorper ac, suscipit eget, massa. Sed suscipit ipsum at mauris. Ut aliquam orci ullamcorper ligula. Nam sed arcu et nulla volutpat egestas.</p>
<p>Integer a nisl. Etiam lectus magna, pulvinar consectetuer, elementum vitae, luctus rutrum, lacus. Cras leo. In faucibus, dui a tempor volutpat, purus magna nonummy ante, nec bibendum erat nunc convallis arcu. Praesent convallis. Mauris non libero. Vivamus nunc. Sed diam. Morbi pulvinar nulla sodales ipsum. Nam ac turpis eget ipsum consequat euismod.</p>
</div>
<button type="button" onclick="dosColumnas()">Dos columnas</button>
<script type="text/javascript">
<!--
// altura total del documento
var doc_height = document.body.clientHeight || window.innerHeight;
// document.getElementById abreviado
function $(x) { return document.getElementById(x); }
/*
El código coge cada palabra de la capa $("elArticulo"), y la mete en un DIV.
Ese DIV se mide en altura y se hallan sus coordenadas.
Se va colocando en columna1 los DIVs, uno por uno.
Siempre sabemos en que número de línea nos encontramos gracias a las coordenadas.
También sabemos el número de líneas que caben gracias a que medimos el alto de una palabra y el alto del DIV columna1.
Cuando colocamos una palabra (o un salto de línea) y nos hemos pasado de la cantidad lineasCaben de columna1, entonces pasamos a poner palabras en columna2.
*/
function dosColumnas() {
var capa = $("elArticulo");
var hijos = capa.childNodes;
// voy a dibujar las dos columnas en la capa
var columnata = document.createElement("DIV"); // columnata contiene las dos columnas c1 y c2
columnata.className = "columnata";
var c1 = document.createElement("DIV");
columnata.style.height = c1.style.height = 0.8*doc_height +"px";
c1.className = "columna";
var c2 = c1.cloneNode(true);
columnata.appendChild(c1);
columnata.appendChild(c2);
capa.appendChild(columnata);
// fin del dibujo de las dos columnas
// Variables principales para ir colocando palabra por palabra
var loPongoEn = c1; // controlará en qué columna ponemos las palabras
var alturaMaxLoPongoEn = loPongoEn.offsetHeight; // la altura de loPongoEn
var lineasCaben; // no lo sabemos aún porque no sabemos lo que mide una línea
var lineasVamos=0; // contador para saber por qué linea vamos
var x0; // valor de la coordenada x de una palabra para la que empieza una linea nueva.
// Bucle para recorrer los párrafos de capa, uno a uno
for(var i=0, l=hijos.length; i<l; i++) {
if( hijos[i].nodeType==1 && hijos[i].tagName.toUpperCase()=="P" ) {
var texto = hijos[i].childNodes[0].nodeValue;
var palabras = texto.split(" ");
// Por cada palabra del párrafo, la vamos añadiendo
for(var j=0, n=palabras.length; j<n; j++) {
var encapsulado = document.createElement("DIV"); // creamos el DIV
encapsulado.className = "pal"; // lo ponemos inline
encapsulado.appendChild( document.createTextNode(palabras[j]) ); // le dibujamos la palabra al DIV
loPongoEn.appendChild(encapsulado); // lo añadimos a la columna
loPongoEn.appendChild( document.createTextNode(" ") ); // añadimos a la columna el espacio detrás de la palabra
if( lineasCaben == undefined ) // si no estaba definido lineasCaben, ahora lo podemos definir
lineasCaben = Math.floor( alturaMaxLoPongoEn / (encapsulado.offsetHeight+1) );
var pos = findPos(encapsulado)[0]; // hallamos su coordenada X
if( x0 == undefined ) x0 = pos; // si x0 no estaba definido, ahora que colocamos la primera palabra la podemos definir
else if( x0 == pos ) lineasVamos++; // si comenzamos una nueva línea, la contabilizamos
if( lineasVamos >= lineasCaben ) { // Hemos puesto una línea más de las que cabían. Nos tenemos que arrepentir de haber puesto la ultima palabra
loPongoEn.removeChild( loPongoEn.lastChild ); // eliminamos el espacio en blanco (nodo de texto)
loPongoEn.removeChild( loPongoEn.lastChild ); // eliminamos la última palabra, la de arrepentimiento
j--; // repetir la palabra, pero ya en c2
// reseteamos las variables principales
loPongoEn = c2;
lineasVamos = 0;
x0 = undefined;
}
}
loPongoEn.appendChild( document.createElement("P") ); // dejamos un espacio entre párrafo y párrafo
lineasVamos++; // contabilizamos el espacio como linea nueva
if( lineasVamos >= lineasCaben ) { // Hemos puesto una línea más de las que cabían. Nos tenemos que arrepentir de haber la última separación P
loPongoEn.removeChild( loPongoEn.lastChild ); // eliminamos la separación
// reseteamos las variables principales
loPongoEn = c2;
lineasVamos = 0;
x0 = undefined;
}
}
}
// Eliminación del texto original
// elimino todos los hijos de capa que no sean DIVS!
for(var i=0; i<hijos.length; i++) {
if( !(hijos[i].nodeType==1 && hijos[i].tagName.toUpperCase()=="DIV") ) {
capa.removeChild( hijos[i] );
i--;
}
}
}
// créditos findPos: http://www.quirksmode.org/js/findpos.html
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft
curtop += obj.offsetTop
}
}
return [curleft,curtop];
}
// -->
</script>
</body>
</html>
Bueno, a ver si os gusta. Se podría implementar y todo con confianza, pero no he probado a aumentar tamaños de texto ni a jugar con formatos...
Otra manera de hacerlo sería incluir párrafo por párrafo, y allí donde nos pasemos de la altura máxima de la columna entonces desmigajamos el párrafo en palabras...
Un saludo, y feliz 2008 ya