2014-10-22 38 views
5

Ho cercato su Google per oltre una settimana ora, ho cercato di implementare diverse soluzioni, ma senza successo, e sta rovinando tutto di me.contenteditable - Selezione di 2 paragrafi figlio e scrittura di testo su (numero di Firefox)

Quindi si dispone di un div contentedit con diversi paragrafi (o altri elementi figlio dello stesso tipo). Ovviamente questo è il tipo di layout che vuoi mantenere. Se l'utente seleziona due o più paragrafi e tipi di testo su di esso, rimuove i paragrafi e imposta la messa a fuoco punto di inserimento all'interno del div genitore:

body { 
 
    font-family: georgia; 
 
} 
 
.editable { 
 
    color: red; 
 
} 
 
.editable p { 
 
    color: #333; 
 
} 
 
.editable span { 
 
    color: limegreen !important; 
 
}
<div class="editable" contenteditable><p>paragraph one</p><p>paragraph two</p></div> 
 

 
<hr> 
 
    
 
<p>How to reproduce the bug:</p> 
 
<ul> 
 
    <li>Focus the contenteditable above by placing the cursor somewhere in one of the two paragraphs.</li> 
 
    <li>press ctrl-a (in windows or linux) or cmd-a (in osx) to select-all</li> 
 
    <li>type some text</li> 
 
    <li>red text means that the text went directly inside the contenteditable div, black text means it went inside a paragraph</li> 
 
</ul> 
 
    
 
<p>The correct behaviour should be that that select-all and delete (or "type-over") in a contenteditable with only block tags should leave the cursor inside the first block tag.</p> 
 
    
 
<p>Webkit gets this right, Firefox gets it wrong.</p>

Ho provato qualcosa di simile in Jquery:

$(document).on('blur keyup','div[contenteditable="true"]',function(event){ 
    var sel = window.getSelection(); 
    var activeElement = sel.anchorNode.parentNode; 
    var tagName = activeElement.tagName.toLowerCase(); 
    if (!(tagName == "p" || tagName == "span")) { 
     console.log('not on editable area'); 
     event.preventDefault(); 
     //remove window selection 
     var doselect = window.getSelection(); 
     doselect.removeAllRanges(); 
    } 
}); 

Così, dopo sfocatura o evento keyup su contenteditable, rilevare dove la posizione del cursore e le aree modificabili se è al di fuori accettato di fermare la manifestazione o qualcosa del genere?

Ho provato a cambiare la gamma di selezione e un mucchio di altre cose, ma forse non lo vedo. Sono sicuro che molte persone hanno avuto lo stesso problema, ma le uniche risposte che ho trovato su Google o qui sono "content editable sucks", "perché non usi un editor open source" e quel tipo di cose.

Firefox strano comportamento: Inserimento di tag BR sulla linea di rottura ho anche provato a rimuovere Firefox'es strano comportamento di una funzione per rimuovere tutti i <BR> tag firefox inserisce automaticamente. Come questo:

function removeBr(txteditor) { 
    var brs = txteditor.getElementsByTagName("br"); 
    for (var i = 0; i < brs.length; i++) { brs[i].parentNode.removeChild(brs[i]); } 
} 

Così ho attaccato ad un evento keydown, e fa esattamente quello che ci si aspetta, tuttavia, che provoca un comportamento più bizzarro (come la prevenzione si aggiunge spazi sul paragrafo selezionato).

Si prega di votare la domanda in modo che possiamo aumentare la consapevolezza.

Sono sicuro che molte altre persone si sono imbattute nello stesso problema, penso che sarebbe bello sapere se c'è una soluzione o un modo "giusto" per farlo. Penso che dovrebbe essere davvero discusso ...

+2

Non esiste uno standard quindi è ingiusto definire il comportamento di Firefox "sbagliato". –

risposta

1

Che cosa sta succedendo è questo, quando si selezionano entrambi i gruppi di testo e li si elimina anche l'eliminazione di tutti i tag all'interno dell'elemento modificabile. Quindi in realtà stai eliminando i tag <p> dal div e quindi l'unica cosa su cui scrivere è il div stesso.

Perché sono necessari due tag di paragrafo separati? Sarebbe più facile per avere il div di per sé ... Invece di impostare il div come modificabile, hai provato l'impostazione dei tag <p> come <p contenteditable="true">

+0

Beh, perché quando hai 2 tag di paragrafo in un div che è contenteditable allora ogni volta che premi invio, crea un altro paragrafo. Se rendi contenteditable ogni paragrafo, non sarai in grado di selezionare più paragrafi ... –

+0

e sì, sappiamo che seleziona entrambi i paragrafi, la domanda è come risolverlo. Se provi la stessa cosa in Chrome o IE ottieni un risultato diverso. La domanda è come rendere il comportamento coerente in tutti i browser. –

+0

'var children = $ ("# edit"). Children(); if ($ (children) .length == 0) { $ ("# edit"). Html ("

"); } ' questo restituirà quanti bambini esistono nel div con un id di modifica. inserire questo evento in un evento di pressione e dovrebbe rimettere il tag del paragrafo ogni volta che vengono cancellati. –

2

Quindi Firefox inietta questo abominio - <br></br> - nel div contenteditable quando si rimuove la paragrafi.

Con un po 'di jQuery possiamo rimuoverlo e sostituirlo con i tag di paragrafo.

Limite di corrente - Il tag di interruzione sembra essere iniettato solo quando rimosso con delete o backspace, non quando digitato sopra ...considerare questo un concetto :-)

Apri questo esempio in Firefox per prova:

$("button").click(function() { 
 

 
$("br:not(p br)").replaceWith('<p>Write Me!</p>'); // dont replace when inside p 
 
});
body { 
 
    font-family: georgia; 
 
} 
 
.editable { 
 
    color: red; 
 
} 
 
.editable p { 
 
    color: #333; 
 
} 
 
.editable span { 
 
    color: limegreen !important; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div class="editable" contenteditable> 
 
    <p>paragraph one</p> 
 
    <p>paragraph two</p> 
 
</div> 
 

 
<hr> 
 

 
<p>Remove all text to trigger bug in Firefox and hit "fix problem!"</p> 
 

 
</ul> 
 

 
<p>Webkit gets this right, Firefox gets it wrong.</p> 
 

 
<button class="fix">Fix Problem</button>

+0

sì, ho notato che, ho provato un approccio simile ma ancora non si comporta come previsto ... Vedi la mia modifica sulla mia domanda –