2010-01-06 53 views
36

Estaba mirando this question y vi la referencia al juego de iPhone donde arrastras la pantalla seleccionando letras sobre la marcha.Seleccionar celdas en una tabla arrastrando

Tenía curiosidad por ver una implicación de esto en JavaScript usando tablas. Así que arrastras el mouse sobre cada celda y luego se resaltan.

No estoy seguro de cuál sería el mejor método, pero espero que alguien tenga una oportunidad. Alguien lo intentó here, pero en realidad no funciona.

alt textalt text

Gracias Cacoo para los diagramas atractivas. Es como una visio en línea, realmente agradable. Check it out;)

+1

desafío interesante (y diagramas). El truco será evitar la selección de texto predeterminada en el navegador ... – tbeseda

Respuesta

66

Aquí hay un prototipo funcional: http://jsfiddle.net/few5E/ Uso de jQuery para el enganche DOM, pero podría implementarse fácilmente con otro marco.

Actualización: http://jsfiddle.net/Brv6J/ una versión ligeramente diferente: el estado resaltado solo cambiará cuando lo suelte y vuelva a hacer clic.

Actualización 2: http://jsfiddle.net/Brv6J/3/ - vinculando onselectstart para que el texto no esté seleccionado en IE.

Algunos datos relevantes:

  • el evento MouseDown de las celdas de la tabla se engancha a rastrear el clic real. Este evento se detiene, por lo que la selección de texto se ve obstaculizada. También vinculante ontextselect para el mismo efecto en IE.
  • El evento mouseover alternará la clase resaltada para la celda
  • El evento mouseout está enganchado en document. Esto es para garantizar que siempre se ejecute. Si el evento mouseup se enganchó en la celda de la tabla, no se activaría si soltó la tecla del mouse con el mouse fuera de la tabla. Este estado se rastrea en isMouseDown.

El código fuente completo de referencia:

<!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="en" lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
    <title></title> 
    <style type="text/css" media="screen"> 
    table td { 
     width:100px; 
     height:100px; 
     text-align:center; 
     vertical-align:middle; 
     background-color:#ccc; 
    } 

    table td.highlighted { 
     background-color:#999; 
    } 
    </style> 
</head> 
<body> 
    <table cellpadding="0" cellspacing="1" id="our_table"> 
    <tr> 
     <td>a</td> 
     <td>b</td> 
     <td>c</td> 
    </tr> 
    <tr> 
     <td>d</td> 
     <td>e</td> 
     <td>f</td> 
    </tr> 
    <tr> 
     <td>g</td> 
     <td>h</td> 
     <td>i</td> 
    </tr> 
    </table> 

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script> 
    <script type="text/javascript" charset="utf-8"> 
    $(function() { 
     var isMouseDown = false; 
     $("#our_table td") 
     .mousedown(function() { 
      isMouseDown = true; 
      $(this).toggleClass("highlighted"); 
      return false; // prevent text selection 
     }) 
     .mouseover(function() { 
      if (isMouseDown) { 
      $(this).toggleClass("highlighted"); 
      } 
     }) 
     .bind("selectstart", function() { 
      return false; // prevent text selection in IE 
     }); 

     $(document) 
     .mouseup(function() { 
      isMouseDown = false; 
     }); 
    }); 
    </script> 
</body> 
</html> 
+1

Es interesante que use toggleClass ... en este caso, cuando se desplaza hacia atrás a una celda que ya está seleccionada, esto elimina la selección. Esto puede o no ser correcto en función de la lógica de la aplicación. Intuitivamente (y como lo hago en mi solución), lo mantengo seleccionado hasta el mouseup. – Jaanus

+1

Ver el enlace alternativo :) Acabo de agregarlo. –

+1

El uso de toggleClass es solo un truco, por así decirlo. En una implementación verificable de la unidad adecuada, usaría una instancia con un booleano, o algo así. –

11

http://www.jaanuskase.com/stuff/dragSelect.html

No estoy seguro de si quería aplicación pura en Javascript, he usado jQuery para mayor comodidad.

+0

De todos modos, ¿puede refactorizar fácilmente esto para apoyar también eventos táctiles? – hlyates

+0

@hlyates algún consejo sobre cómo refactorizar algo como esto para apoyar los eventos táctiles? – maco1717

8

Si después de selección de celda de hoja de cálculo (en la columna/fila de bloques), es necesario resaltar cada célula en cada fila que se encuentra entre su iniciar & índice final (tanto fila y celular) en su evento mouseover:

for (var i = rowStart; i <= rowEnd; i++) { 
    var rowCells = table.find("tr").eq(i).find("td"); 
    for (var j = cellStart; j <= cellEnd; j++) { 
     rowCells.eq(j).addClass("selected"); 
    }   
} 

a medida que el usuario puede empezar a seleccionar las células de todas las direcciones (arriba-abajo, de abajo hacia arriba, de derecha a izquierda, de izquierda-derecha) necesita asignar el correcto índices para el inicio & final.

Aquí hay un jsFiddle.

+0

Mejor, usaría Dojo o jQuery (o algo incluso de nivel superior) – paulsm4

+0

Agregar 'tabla. find (". selected"). removeClass ("selected"); 'en la función' mouseover' para que sea más parecido a una hoja de cálculo, es decir, anule la selección de celdas cuando se mueve sobre un área seleccionada. Actualizado [violín] (http://jsfiddle.net/chechs/qvw0pgcu/22/) – User528491

+0

@ User528491 Buen lugar. Violín base actualizado. Gracias. – Martin

Cuestiones relacionadas