2011-07-08 29 views
12

¿Es posible seleccionar el texto (es decir, tenerlo resaltado para que se pueda copiar y pegar) de cada celda en una columna vertical de una tabla HTML?Seleccionar texto en una columna de una tabla html

¿Hay un método de JavaScript, o quizás un equivalente en algunos navegadores para el atajo de Alt-Click-Drag usado en muchos editores de texto?

¿O es esto imposible?

+2

+1 para una buena pregunta, pero sospecho que es imposible. ¿Conoce alguna forma en que el usuario pueda hacer lo mismo manualmente? – nnnnnn

+0

No, de ninguna manera directa ... – cbp

Respuesta

8

Lo que estás buscando se llama Range objeto (TextRange en IE).

Actualización: Aquí hay un código de trabajo para hacer lo que usted sugiere: http://jsfiddle.net/4BwGG/3/

Mientras captura contenido de las celdas, puede dar formato a los mismos en cualquier manera que usted desee. Simplemente agrego una nueva línea cada vez.

Nota:

  • funciona bien en FF 3 y superior
  • IE (antes de las 9) y Chrome no admite la selección múltiple.
  • Chrome no resalta todas las celdas (pero captura todo el contenido). Lo mismo vale para IE9
  • IE 7 & 8 arrojará un error.

Una alternativa es aplicar un estilo CSS que simula destacando el clic del encabezado de la columna y el bucle a través de todas las células para captar su contenido. La apariencia de este enfoque puede diferir del aspecto de la selección nativa (a menos que capture de alguna manera el evento seleccionado y modifique la apariencia).

A continuación, utilice el complemento de copia de jQuery para copiarlos en el portapapeles.

+0

¿Esto no solo selecciona una celda? ¡Quiero seleccionar la columna completa! – cbp

+0

Esto es solo código de demostración. Si desea una columna completa, repita el proceso para todos los 'TD's – Mrchief

+0

¿Por qué el voto a favor? – Mrchief

3

Usted podría tener un div, que se rellena con los datos de columna de clic y aplicar una clase CSS para dar las columnas de la apariencia de ser seleccionado

algo como esto:

var $mytable = $("#mytable"), 
    $copydiv = $("#copy_div"); 

$mytable.find("td").click(function(){ 

    //get the column index 
    var $this = $(this), 
     index = $this.parent().children().index($this); 

    //find all cells in the same column 
    $mytable.find("tr:nth-child(" + index + ")").removeClass("selected").each(function() { 
     var $this = $(this); 
     $this.addClass("selected"); 
     $copydiv.html($this.html() + "<br />"); 
    }); 
}); 

o usted podría tener una tabla separada para cada columna, pero no creo que valga la pena.

6

Algunas herramientas de revisión de código implementan esto para permitir la copia & pegando el código desde un lado de un lado a lado diff. Miré cómo ReviewBoard lo quita.

Lo esencial es:

  1. Cuando comienza una selección de columna, estilo las células en todas las demás columnas con user-select: none (y sus variantes prefijados, if necessary). Esto crea la apariencia de una selección de columna. Las otras columnas todavía se seleccionan en secreto, por lo que debe ...
  2. Interceptar el evento copy y cambiar su carga para reflejar el contenido de la columna seleccionada.

El código de ReviewBoard para hacer esto consiste en this CSS y this JavaScript.

Lo saqué en un mínimo jsbin demo.

Aquí está el CSS para crear la apariencia de una selección de una sola columna (agregar la clase selecting-left a la mesa cuando se está seleccionando la columna de la izquierda, o selecting-right de la derecha):

.selecting-left td.right, 
.selecting-left td.right *, 
.selecting-right td.left, 
.selecting-right td.left *, 
    user-select: none; 
} 

.selecting-left td.right::selection, 
.selecting-left td.right *::selection, 
.selecting-right td.left::selection, 
.selecting-right td.left *::selection, 
    background: transparent; 
} 

Aquí está la JavaScript para interceptar el evento copy y enchufe en el valor de una sola columna de datos:

tableEl.addEventListener('copy', function(e) { 
    var clipboardData = e.clipboardData; 
    var text = getSelectedText(); 
    clipboardData.setData('text', text); 
    e.preventDefault(); 
}); 

function getSelectedText() { 
    var sel = window.getSelection(), 
     range = sel.getRangeAt(0), 
     doc = range.cloneContents(), 
     nodes = doc.querySelectorAll('tr'), 
     text = ''; 

    var idx = selectedColumnIdx; // 0 for left, 1 for right 

    if (nodes.length === 0) { 
    text = doc.textContent; 
    } else { 
    [].forEach.call(nodes, function(tr, i) { 
     var td = tr.cells[tr.cells.length == 1 ? 0 : idx]; 
     text += (i ? '\n' : '') + td.textContent; 
    }); 
    } 

    return text; 
} 

también hay algo de código sea menos interesante añadir los selecting-left y selecting-right cl culos al comienzo de una selección. Esto requeriría un poco más de trabajo para generalizar a las tablas de n columnas.

Esto parece funcionar bien en la práctica, ¡pero es sorprendente lo difícil que es!

+1

Esta debería ser la respuesta aceptada. El mencionado arriba no funciona en absoluto. –

+0

Funciona en FF, Chome? – seebiscuit

+0

Se rompió en Firefox. Actualicé el enlace de demostración y debería funcionar ahora. El cambio estaba eliminando '-moz-user-select: -moz-none'. Las nuevas versiones de Firefox entienden 'ninguno'. El comportamiento copiar/pegar siempre funcionó en FF, era solo la pantalla que se rompió. – danvk

Cuestiones relacionadas