Estoy trabajando en un editor en el navegador dentro de una textarea. He empezado a buscar un poco de información sobre el tratamiento con textarea de selección y se encontró este plugin de jQuery, fieldSelection que hace una simple manipulación.

Sin embargo, no explica lo que está pasando.

Quiero entender más sobre textarea selección en JavaScript, preferiblemente con una descripción tanto de pre-DOM3 y post-DOM30 escenarios.

OriginalEl autor brad | 2008-12-30

4 Comentarios

  1. 10

    Empezar con PPK del introducción a los rangos. Mozilla developer connection tiene info sobre W3C selecciones. Microsoft tiene su sistema de documentado en MSDN. Algunos de los trucos más se puede encontrar en las respuestas aquí.

    Además de incompatible interfaces usted será feliz de saber que hay más bizarro pasando con textarea nodos. Si recuerdo correctamente, se comportan como cualquier otro de los nodos cuando se seleccionan en IE, pero en otros navegadores tienen una selección independiente de la gama que se expone a través de la .selectionEnd y .selectionStart propiedades del nodo.

    Además, usted realmente debería echar un vistazo a .contentEdiable como un medio para modificar las cosas en vivo. Desde el lanzamiento de Firefox3, esto es ahora soportado por todos los navegadores.

    Gracias Borgar! Nunca he oído hablar de contentEditable antes. Voy a ser familiarizarse con el mismo post de prisa!

    OriginalEl autor Borgar

  2. 29
    function get_selection(the_id)
    {
    var e = document.getElementById(the_id);
    //Mozilla and DOM 3.0
    if('selectionStart' in e)
    {
    var l = e.selectionEnd - e.selectionStart;
    return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) };
    }
    //IE
    else if(document.selection)
    {
    e.focus();
    var r = document.selection.createRange();
    var tr = e.createTextRange();
    var tr2 = tr.duplicate();
    tr2.moveToBookmark(r.getBookmark());
    tr.setEndPoint('EndToStart',tr2);
    if (r == null || tr == null) return { start: e.value.length, end: e.value.length, length: 0, text: '' };
    var text_part = r.text.replace(/[\r\n]/g,'.'); //for some reason IE doesn't always count the \n and \r in the length
    var text_whole = e.value.replace(/[\r\n]/g,'.');
    var the_start = text_whole.indexOf(text_part,tr.text.length);
    return { start: the_start, end: the_start + text_part.length, length: text_part.length, text: r.text };
    }
    //Browser not supported
    else return { start: e.value.length, end: e.value.length, length: 0, text: '' };
    }
    function replace_selection(the_id,replace_str)
    {
    var e = document.getElementById(the_id);
    selection = get_selection(the_id);
    var start_pos = selection.start;
    var end_pos = start_pos + replace_str.length;
    e.value = e.value.substr(0, start_pos) + replace_str + e.value.substr(selection.end, e.value.length);
    set_selection(the_id,start_pos,end_pos);
    return {start: start_pos, end: end_pos, length: replace_str.length, text: replace_str};
    }
    function set_selection(the_id,start_pos,end_pos)
    {
    var e = document.getElementById(the_id);
    //Mozilla and DOM 3.0
    if('selectionStart' in e)
    {
    e.focus();
    e.selectionStart = start_pos;
    e.selectionEnd = end_pos;
    }
    //IE
    else if(document.selection)
    {
    e.focus();
    var tr = e.createTextRange();
    //Fix IE from counting the newline characters as two seperate characters
    var stop_it = start_pos;
    for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) start_pos = start_pos - .5;
    stop_it = end_pos;
    for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) end_pos = end_pos - .5;
    tr.moveEnd('textedit',-1);
    tr.moveStart('character',start_pos);
    tr.moveEnd('character',end_pos - start_pos);
    tr.select();
    }
    return get_selection(the_id);
    }
    function wrap_selection(the_id, left_str, right_str, sel_offset, sel_length)
    {
    var the_sel_text = get_selection(the_id).text;
    var selection =  replace_selection(the_id, left_str + the_sel_text + right_str );
    if(sel_offset !== undefined && sel_length !== undefined) selection = set_selection(the_id, selection.start +  sel_offset, selection.start +  sel_offset + sel_length);
    else if(the_sel_text == '') selection = set_selection(the_id, selection.start + left_str.length, selection.start + left_str.length);
    return selection;
    }
    De todas las soluciones que he visto de este problema, este es el único que ha estado trabajando para mí.
    usted debe tomar los elementos como parámetros en lugar de la Id, lo que hace que sea mucho más flexible. De lo contrario, brillante! Muchas gracias por una visión de otras personas o sitios web no pudo proporcionar.
    Bonito funciones; eran fáciles de adaptar a mis necesidades. Hay un error a pesar de que la captura fuera de IE 6 & 7. En el set_selection una función de «e.valor[i]». Este debe ser cambiado a «e.valor.charAt(i)». Ver: stackoverflow.com/questions/5943726/string-charatx-or-stringx
    Gracias! La única solución que realmente funciona.

    OriginalEl autor user357565

  3. 5

    He adoptado la solución presentada por user357565, y recodificada para jQuery uso directo:

    (function ($) {
    $.fn.get_selection = function () {
    var e = this.get(0);
    //Mozilla and DOM 3.0
    if('selectionStart' in e) {
    var l = e.selectionEnd - e.selectionStart;
    return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) };
    }
    else if(document.selection) {    //IE
    e.focus();
    var r = document.selection.createRange();
    var tr = e.createTextRange();
    var tr2 = tr.duplicate();
    tr2.moveToBookmark(r.getBookmark());
    tr.setEndPoint('EndToStart',tr2);
    if (r == null || tr == null) return { start: e.value.length, end: e.value.length, length: 0, text: '' };
    var text_part = r.text.replace(/[\r\n]/g,'.'); //for some reason IE doesn't always count the \n and \r in length
    var text_whole = e.value.replace(/[\r\n]/g,'.');
    var the_start = text_whole.indexOf(text_part,tr.text.length);
    return { start: the_start, end: the_start + text_part.length, length: text_part.length, text: r.text };
    }
    //Browser not supported
    else return { start: e.value.length, end: e.value.length, length: 0, text: '' };
    };
    $.fn.set_selection = function (start_pos,end_pos) {
    var e = this.get(0);
    //Mozilla and DOM 3.0
    if('selectionStart' in e) {
    e.focus();
    e.selectionStart = start_pos;
    e.selectionEnd = end_pos;
    }
    else if (document.selection) { //IE
    e.focus();
    var tr = e.createTextRange();
    //Fix IE from counting the newline characters as two seperate characters
    var stop_it = start_pos;
    for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) start_pos = start_pos - .5;
    stop_it = end_pos;
    for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) end_pos = end_pos - .5;
    tr.moveEnd('textedit',-1);
    tr.moveStart('character',start_pos);
    tr.moveEnd('character',end_pos - start_pos);
    tr.select();
    }
    return this.get_selection();
    };
    $.fn.replace_selection = function (replace_str) {
    var e = this.get(0);
    selection = this.get_selection();
    var start_pos = selection.start;
    var end_pos = start_pos + replace_str.length;
    e.value = e.value.substr(0, start_pos) + replace_str + e.value.substr(selection.end, e.value.length);
    this.set_selection(start_pos,end_pos);
    return {start: start_pos, end: end_pos, length: replace_str.length, text: replace_str};
    };
    $.fn.wrap_selection = function (left_str, right_str, sel_offset, sel_length) {
    var the_sel_text = this.get_selection().text;
    var selection =  this.replace_selection(left_str + the_sel_text + right_str );
    if(sel_offset !== undefined && sel_length !== undefined) 
    selection = this.set_selection(selection.start +  sel_offset, selection.start +  sel_offset + sel_length);
    else if(the_sel_text == '') 
    selection = this.set_selection(selection.start + left_str.length, selection.start + left_str.length);
    return selection;
    };
    }(jQuery));

    Espero que alguien la encuentre útil!

    Gracias hombre! utiliza tu código y modificar algunas de cuenta para alternar contenedor etc. Quieres incluir nota/link para usted?
    Gracias pero no es necesario.

    OriginalEl autor Fèlix Galindo Allué

  4. 1

    lo único que puedo agregar es que parece (no en realidad probarlo) que este debe desplazarse de todo el camino cada vez que manpulate el contenido. un vistoso remedio es envolver la línea que hace

    e.value =

    con dos líneas para copiar y restaurar scrollTop, así:

    var rememberScrollTop = e.scrollTop;
    e.value = .... (same as in user357565 snippet)
    e.scrollTop = rememberScrollTop;

    OriginalEl autor anon

Dejar respuesta

Please enter your comment!
Please enter your name here