Ver Mensaje Individual
  #6 (permalink)  
Antiguo 07/04/2012, 13:52
furoya
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 22 años
Puntos: 317
Respuesta: textarea ajustable

De nada. Me alegra que te sirviera.

Y encontré el drama de Opera. Es el mismo de IE, pero "bien hecho". O masomenos.

En vez de poner las etiquetas <p> adentro del <span>, lo que hace al insertar un break (con la tecla [Intro]) es :
  1. Capturar la posición donde se encuentra el break o salto de línea.
  2. Dividir el span en 2 span's por ese punto de salto.
  3. Rodear a cada uno con etiquetas <p> para crear los párrafos.
Un ejemplo de correción semántica este Opera. Porque pensemos que nosotros vamos a capturar el texto plano, pero lo que se está escribiendo en esa caja es HTML; por eso está la creación de párrafos, para separar cada línea de texto con formato.
Y éste vendría a ser el problema. Porque para respetar los formatos previos, a cada span le deja los atributos originales. Quiero decir, que al "segundo" le copia los que tenga el "primero".
Y si tiene un id, también lo duplica.

De esa forma, el CSS no encuentra el primero(*), y el JS ignora el último.

Podríamos suponer que con innerText nos ahorramos todos problemas de reemplazo y de etiquetas agregadas, pero sucede que Firefox no lo reconoce (usa textContent), y navegadores como Opera o Chrome no ven los caracteres de 'nueva línea' y 'retorno de carro', y muestran el texto todo de corrido.
Así que seguimos con el innerHTML, que es compatible con todos.

Otra cuestión que no mencionamos arriba es qué pasa cuando no tipeamos en el "truchárea", sino que pegamos o cortamos texto desde el menú de herramientas o el menú contextual. El evento de teclado no se dispara y el escript no se ejecuta, por supuesto.

La forma compatible que usé para corregir la siguiente versión, es el evento onblur. Solamente muestra el cambio al salirse el foco del editable, pero si se va a enviar el contenido a algún lado, seguramente hay que ir a un botón. Al clickearlo cambia el foco y actualiza la variable cont, y recién después la envía.

No pude probarlo todavía en IE, pero creo que va a funcionar. Si alguien quiere hacer el betatesting, le agradezco.

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>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>TEXTAREA TRUCHO AUTOAJUSTABLE.</title>
<script type="text/javascript">

var ref , cont = ":-)";

function sapeartextarea(){

ref = document.getElementById("textareaTrucho");

document.getElementById("guardatxt").style.height = ref.offsetHeight + "px";

document.getElementById("guardatxt").style.width =
(ref.offsetWidth > 400)? ref.offsetWidth + "px" : "400px";

cont = ref.innerHTML.replace(/<p>/gi , "").replace(/&nbsp;/gi , " ").replace(/<br>|<\/p>/gi , "\r\n");

document.getElementById("codigo").value = cont;

}

function limpiartextarea(){

document.getElementById("textareaTrucho").innerHTML="";

sapeartextarea();

}
</script>
<style type="text/css">

#guardatxt { width: 400px; height: 1em; overflow: hidden; padding: 0.2em; 
border: solid 1px black; }

#textareaTrucho { font: normal 16px/16px monospace; background: yellow; 
display: inline-block; min-height: 1em; min-width: 1em;}

</style>
</head>
<body>
<h2>Simula un <code>textarea</code> que ajusta su tamaño al contenido. </h2>

<input type=button value="ENVIAR" onclick=alert(cont)> 
<input type=button value="LIMPIAR" onclick=limpiartextarea()> 

<div id=guardatxt>
<div contenteditable=true id=textareaTrucho onkeyup=sapeartextarea() 
onblur=sapeartextarea()>Texto de prueba en campo editable.</div>
</div>

<hr>

<p style="font-family: 'arial unicode ms', quivira, symbola, titus;">( Aquí se ve cómo será 
enviado el contenido del falso <code>textarea</code> :<br>&nbsp; &#x261f;</p>

<textarea id=codigo rows=10 cols=50></textarea> 

)

</body>
</html>
Otro pequeño ajuste fue cambiar el span por un div, así el IE también quedará "semanticamente correcto". Además optimicé las expresiones regulares (que los novatos no se asusten, todavía se entienden), y por último agregué unos "min-width ; min-height" para evitar que al borrarle todo el contenido el editable "colapsara" y ya no mostrase un lugar donde hacer foco con el maus (ratón). El botón "LIMPIAR" está para la comodidad de hacer las pruebas, tiene una función aparte.


Insisto, cualquier mejora es bienvenida ... Hasta que los navegadores implementen su propio modo para leer el tamaño del valor de los textarea; y todo esto no sirva para nada.

Saludos
furoya


(*) : Aunque no sea correcto, los navegadores nuevos aplican formatos CSS a los id repetidos, como si se tratara de clases.