Ver Mensaje Individual
  #1 (permalink)  
Antiguo 29/09/2007, 06:11
Avatar de PosProdukcion
PosProdukcion
 
Fecha de Ingreso: noviembre-2004
Ubicación: Manzanares el Real (Madrid)
Mensajes: 726
Antigüedad: 19 años, 5 meses
Puntos: 9
Determinar rango seleccionado en TextArea (internet explorer)

Hola, hace 4 días que estoy pelándome con un textarea y como determinar, en Internet Explorer la posición que ocupa el cursor, en caso de no haber selección, o las posiciones de inicio y fin de seleccion en caso de haber seleccion, modificar ese texto y volver a colocarlo después.

Lo que en FireFox se resuelve con 4 líneas de código (2 para leer la posición y otras 2 para volver a colocarlo después de hacer lo que sea que quieres hacer con ello), en IExplore me ha llevado 100 líneas de código!!! y muchos quebraderos de cabeza. No he encontrado mucha información al respecto en internet así que pongo aquí las funciones, que en realidad son una adaptación de una solución que he visto en la sección de comentarios de un blog en internet, (ver comentario XV), aunque no funcionaba del todo bien.

En fin, que pongo aquí el código por si alguien lo necesita algún día, maneja un objeto js_CursorPos con propiedades sstar y end...

Código:
    //Cuenta los caracteres en el texto sin contar los retornos de carro
    function js_countTextAreaChars(text)
    {
        var navegador = navigator.userAgent.toLowerCase();
        var n = 0;
        for (var i = 0; i < text.length; i++)
        {
               if (text.charAt(i) != '\r')
                    n++;
        }
        return n;
    }

    //Crea el objeto con las posiciones de Inicio y Fin de la seleccion
    function js_CursorPos(sstart, end) {
        this.sstart = sstart;
        this.end = end;
    }

    //Lee las posiciones de incio y fin del cursor o la seleccion en textArea
    function js_getCursorPosition(textArea)
    {
        var sstart = 0;
        var end = 0;
        //var textArea = document.getElementById(editor);
        var comodin = String.fromCharCode(28);

        if (document.selection)
         { // IE…
            textArea.focus();

            var sel1 = document.selection.createRange();

            var stored_range = sel1.duplicate();

            stored_range.moveToElementText( textArea ); // Now move 'dummy' end point to end point of original range
            stored_range.setEndPoint( 'EndToEnd', sel1 ); // Now we can calculate start and end points
            //Ahora stored_range.text tiene desde el comienzo del textarea hasta fin de seleccion - alert('Ahora stored_range.text ' + stored_range.text);

            //var diferencia = stored_range.text.length - sel1.text.length;
            sstart = stored_range.text.length - sel1.text.length;
            end = sstart + sel1.text.length;
        }
        else if (textArea.selectionStart || (textArea.selectionStart == '0'))
        { // Mozilla/Netscape…
            sstart = textArea.selectionStart;
            end = textArea.selectionEnd;
        }
        //alert('Inicio en ' + start + '; fin en ' + end)
        //AL retornar fija las posiciones de inicio y fin
        return new js_CursorPos(sstart, end);
    }

    //internet explorer al posicionar el inicio y fin de la
    //seleccion, estas posiciones se desplaza hacia adelante tantas posiciones
    //como cambios de linea haya delante de esa posicion
    //Esta funcion cuenta los cambios de linea antes de una posicion dada
    function js_cuentaCambiosDeLineaAntes(texto, posicion)
    {
        var trozo = texto.substring(0, posicion);
        var numCL;
        var car;
        numCL = 0;
        for (i=0; i<= trozo.length; i++)
        {
            if (trozo.charAt(i) == '\n')
                numCL++;

        }
        return numCL;
    }

    //Coloca el cursor o la seleccion en las posiciones de inicio y fin fijadas para textArea
    function js_setCursorPosition(textArea, cursorPos)
    {
        //var textArea = document.getElementById('txtBB001');
        if (document.selection)
        { // IE…
            var sel = textArea.createTextRange();
            var numCL;
            var nuevoComienzo;

            numCL = js_cuentaCambiosDeLineaAntes(sel.text, cursorPos.sstart);
            sel.collapse(true);

            //El puto IE hace lo que le sale de los cojones y hay que retroceder
            //el numero de  cambios de linea anteriores a la seleccion
            if (cursorPos.sstart >= numCL)
                nuevoComienzo = cursorPos.sstart - numCL;
            else
                nuevoComienzo = cursorPos.sstart;

            sel.moveStart('character', nuevoComienzo); //Coloca el inicio y fin de la seleccion
            sel.moveEnd('character', cursorPos.end - cursorPos.sstart);
            sel.select();
        }
        else if (textArea.selectionStart || (textArea.selectionStart == '0'))
        { // Mozilla/Netscape…
            textArea.selectionStart = cursorPos.sstart;
            textArea.selectionEnd = cursorPos.end;
        }
        textArea.focus();
    }
Todavía tiene un bug cuando el cursor está al comienzo de una línea y no hay selección la función se mueve al final de la última con contenido (es decir, si hay varios cambios de línea antes del cursor no los detecta, pero ya no tengo ganas de seguir con ello, se queda con el bug que no es mío, es de microsoft

Y lo siento pero tengo que decir esto, moderador puedes editar si lo crees necesario: ME CAGO EN LA #### MADRE QUE PARIO A MICROSOFT, si la pagina fuera para mi desde luego no me iba a preocupar por los bugs de microsoft y sus chapuzas, pero como es para un cliente estoy obligado a ello

Saludos

Última edición por PosProdukcion; 29/09/2007 a las 07:59