7

Sto sovrapponendo il testo invisibile sopra un'immagine. C'è un plugin jQuery (o simile) che permetterà agli utenti di selezionare un'area sull'immagine (che seleziona anche il testo sovrapposto) e di essere in grado di copiare il contenuto.jQuery - seleziona il testo invisibile sovrapposto all'immagine, ala GMail PDF viewer

In questo momento, ho inserito ciascun carattere nel suo tag <span />. Il problema si verifica quando l'utente seleziona, a volte seleziona tutto il testo sovrapposto (a meno che l'utente non sia estremamente preciso con il mouse), a volte l'immagine stessa viene selezionata, ecc.

Una soluzione simile al visualizzatore di file PDF di GMail sarebbe piacevole. Suggerimenti?

+3

significato "invisibile"? è visualizzato none, forecolor = backcolor, visible false? C'è un plugin per il ritaglio di immagini jquery che ti permette di selezionare un'area su un'immagine, ma la parte di testo che dovrai codificare un po '. –

risposta

8

Google sembra sapere da un pdf in cui i vari offset di testo x,y sono nel file. Quando selezioni un gruppo di linee, posiziona un set di "selezioni" di posizione assolutamente posizionate sull'immagine in cui si trova il "testo" (hanno classe highlight-pane). Quando selezioni del testo, riempie un'area di testo #selection-content con il contenuto di ciò che hai selezionato e seleziona il testo al suo interno (prova a utilizzare window.getSelection().anchorNode in Chrome, ad es.). Oltre a queste sovrapposizioni di selezione, c'è solo un'immagine .page-image. Scommetto che in realtà usano la finestra per catturare tutti i gesti del mouse di cui si preoccupano (presumo mousedown e mouseup). (Here's an example pdf document)

Se stai assoluta-posizionamento degli elementi, si potrebbe rilevare mousedown, mousemove e mouseup, capire il mouse elementi span è finito (o al più vicino a), e compilare una textarea con il contenuto di tutte contenuto tra questi due elementi. Se si desidera utilizzare solo la parola-granularità, dubito che qualcuno si lamenterebbe (circondare ogni parola con una spanna, piuttosto che ogni lettera).

Edit: ho avuto un pò curiosa la notte scorsa e codificato un davvero versione ingenuo. Lo fa solo mousedown e mouseup, e non funziona in IE (non mi sento come il debug it :)

Check it out on jsfiddle.

Caratteristiche si potrebbe desiderare di aggiungere:

  1. alcuni meglio modo di controllare le partite basate sulla posizione; Lo faccio solo se è incluso nella confezione.
  2. aggiornamento dinamico su mousemove
  3. line-based, piuttosto che basata sull'estensione
  4. si potrebbe ancora fare la selezione in base al colore di sfondo, ma a seconda di come gli elementi sono disposti potrebbe non sembrare molto buona. Inoltre dovrebbe sostenere la trasparenza.
+0

+1 per la dedica e la risposta asso :) – hookd

+0

@hookd Grazie! Mi ha un po 'agganciato, almeno per la rapida dimostrazione del concetto. – theazureshadow

1

Ecco un semplice esempio usando la mia risposta alla tua domanda precedente: http://www.jsfiddle.net/yijiang/83W7X/2/embedded/result

var selected = []; 

function drawSelection(){ 
    if(selected.length){ 
     selected.sort(function(a, b){ 
      if(a.sourceIndex){ 
       return a.sourceIndex - b.sourceIndex; 
      } else if(a.compareDocumentPosition){ 
       if(a.compareDocumentPosition(b) == Node.DOCUMENT_POSITION_PRECEDING){ 
        return 1; 
       } else { 
        return -1; 
       } 
      } 
     }); 
     var range = rangy.createRange(), 
      sel = rangy.getSelection(); 

     range.setStart(selected[0].children[0], 0); 
     range.setEnd(selected[selected.length - 1].children[0], 1); 
     sel.setSingleRange(range); 
    } 
} 

$('ul').selectable({ 
    delay: 100, 
    selecting: function(event, ui) { 
     if(ui.selecting.getAttribute('class').indexOf('wrapper') !== -1 && $.inArray(ui.selecting, selected) === -1) { 
      selected.push(ui.selecting); 
      drawSelection(); 
     } 
    }, 
    unselecting: function(event, ui){ 
     if(ui.unselecting.getAttribute('class').indexOf('wrapper') !== -1 && $.inArray(ui.unselecting, selected) > -1){ 
      selected.splice($.inArray(ui.unselecting, selected), 1); 
      drawSelection(); 
     } 
    } 
}); 

Si mescola selezionabile di jQuery UI con eccellente biblioteca Rangy di Tim Giù per creare qualcosa di simile a quello che hai chiesto. Credo. Quello che hai chiesto non era esattamente chiaro.

Il codice mantiene una matrice di elementi li attualmente selezionati. La seconda parte del codice viene aggiunta ai gestori di eventi e alle opzioni pertinenti.La funzione drawSelection viene chiamata ogni volta che un elemento viene selezionato o deselezionato. La funzione ordina innanzitutto tutti gli elementi in base alla loro posizione nel DOM, quindi procede a disegnare una selezione dal primo selezionato li all'ultimo.

Il codice, come theazureshadow's, è solo proof-of-concept, poiché sto astrattamente quello che dovrebbe essere il semplice compito di selezionare i li nella libreria Rangy piuttosto pesante. Inoltre non funziona molto bene e potrebbe fare con alcuni refactoring.