CSS: :messa a fuoco di elementi all’interno di contenteditable

Se si ha il seguente codice HTML:

<div contenteditable="true">
  <p>The first paragraph</p>
  <p>The second paragraph</p>
</div>

C’è un modo per stile di paragrafo che viene modificato in modo diverso da tutti gli altri paragrafi del div che è contenteditable?

div > p:focus { border: 1px solid red }

non sarà applicata al paragrafo modificato.

Ecco un JSFiddle si può giocare con.

Come faccio a stile la comma modificato (il <p>-tag) in modo diverso?

Io preferirei un CSS solo la soluzione, ma forse devo usare JavaScript.

EDIT:

Dal momento che non siamo riusciti a trovare un puro CSS soluzione (e :hover non è una vera soluzione per me) ora sto cercando un po di righe di JavaScript che impostare l’attributo class="focus" sul nodo che viene modificato.

  • Per favore mi date un suggerimento su come posso migliorare la mia domanda se si downvote di esso.
  • Gah, ho quasi avuto funzionante – jsfiddle.net/PPNE2/7, proprio non riesco a rimuovere il bordo quando è deselezionata.
  • approccio piacevole
  • hai solo bisogno di mettere contenteditable="true" con ogni p
  • vedere le risposte di seguito.
InformationsquelleAutor pvorb | 2013-05-30

 

3 Replies
  1. 9

    Penso di aver trovato una soluzione.

    Con il seguente frammento di codice, è possibile ottenere l’elemento superiore all’attuale posizione del cursore quando si cambia la selezione.

    var selectedElement = null;
    function setFocus(e) {
      if (selectedElement)
        selectedElement.style.outline = 'none';
    
      selectedElement = window.getSelection().focusNode.parentNode;
      //walk up the DOM tree until the parent node is contentEditable
      while (selectedElement.parentNode.contentEditable != 'true') {
        selectedElement = selectedElement.parentNode;
      }
      selectedElement.style.outline = '1px solid #f00';
    };
    document.onkeyup = setFocus;
    document.onmouseup = setFocus;

    Qui cambia la outline proprietà manualmente, ma naturalmente è possibile aggiungere un attributo di classe e impostare lo stile tramite CSS.

    Si devono ancora verificare manualmente se selectedElement è figlio del nostro <div> con il contenteditable attributo. Ma penso che si può ottenere l’idea di base.

    Ecco il aggiornato JSFiddle.

    EDIT: ho aggiornato il codice così come l’JSFiddle per farlo funzionare su Firefox e Internet Explorer 9+, troppo. Purtroppo questi ultimi non hanno un onselectionchange gestore di eventi, ho avuto modo di utilizzare onkeyup e onmouseup.

    • Questo non funziona in Firefox o IE10 (probabilmente tutti i vecchi IE troppo).
    • Grazie per il suggerimento. Do un’occhiata su di esso.
    • Ho corretto il codice, in modo che funziona in Firefox e IE9+.
    • Così avete fatto! +1 funziona!
    • +1. Che è praticamente quello che avrei suggerito. Una cosa è che questa avrà esito negativo se l’utente rende il testo in grassetto e poi posti il cursore all’interno del testo in grassetto, perché window.getSelection().focusNode.parentNode sarà l’elemento audace, piuttosto che il paragrafo. Mi consiglia di scorrere parentNodes fino a colpire un <p> elemento, invece, vedere stackoverflow.com/a/4642894/96100. Un’altra piccola cosa: la selezione può cambiare senza una chiave o di un evento del mouse cottura (via di Selezionare Tutte le opzioni nel menu browser, per esempio), quindi si consiglia un polling soluzione di ripiego.
    • Sì è vero. Si avrà esito negativo se il markup entro il <div contenteditable="true"> è diverso. Risalendo l’albero del DOM è qualcosa che mi aspetta una possibile figura sulla sua/il suo. Un polling soluzione è sempre un po ‘ sporca, ma probabilmente dovrò aggiungere per completezza. (Anche se non riesco a pensare ad un caso in cui è possibile selezionare un singola paragrafo del <div> senza sparare un mouse o un tasto di evento).
    • Bel lavoro, ragazzi. Una modifica che vorrei fare è utilizzare outline piuttosto che border, come allora, la par non vai in giro come il confine è aggiunto e rimosso.
    • L’ho cambiato. Ma penso che questo è meno importante, per la domanda.
    • Ho anche aggiunto alcune linee che assicurano il nodo principale è contentEditable.

  2. 3

    Domanda interessante. Se è fattibile, io suggerirei di spostare l’attributo contenteditable per il ps stessi: http://codepen.io/pageaffairs/pen/FHKAC

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    
    <style media="all">
    
    div > p:focus {outline: 1px solid red; }
    
    </style>
    
    </head>
    <body>
    
    <div>
        <p contenteditable="true">The first paragraph</p>
        <p contenteditable="true">The second paragraph</p>
    </div>
    
    </body>
    </html>

    EDIT: Ecco un’altra versione, che provoca para torna a generare punti invece di div: http://codepen.io/pageaffairs/pen/dbyIa

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    
    <style media="all">
    
    div:focus {outline: none;}
    div > p:focus, div > p:hover {outline: 1px solid red; }
    
    </style>
    
    </head>
    <body>
    
    <div contenteditable="true">
        <p contenteditable="true">The first paragraph</p>
        <p contenteditable="true">The second paragraph</p>
    </div>
    
    </body>
    </html>
    • In generale, questo è quello che voglio, ma viene fornito con alcuni effetti collaterali: Dire che mi ha colpito di ritorno alla fine dell’ultimo paragrafo. Nella mia versione, un nuovo paragrafo è stato aggiunto. Nella tua versione si inserisce un <div> in che <p>. Strano comportamento… 🙁
    • Jeesh, che strano. Bene, ho aggiunto un altro esempio che sembra funzionare. Unica cosa è che ho dovuto aggiungere passa stili per ottenere la messa a fuoco al lavoro sul paragrafi. Va ‘ a sapere.
    • Mi dispiace, ma è stato hover non è un’opzione per me, perché voglio indicare che il paragrafo si modifica anche quando non si sta utilizzando un mouse. Forse dovrò risolvere che <div> inserimento problema o potrei trovare l’elemento intorno alla posizione corrente del cursore tramite JavaScript.
    • Ho aggiornato la domanda, quindi, JavaScript soluzioni sono generalmente di benvenuto.
  3. 3

    jsFiddle qui.

    Il seguente è imperfetto, nel senso che il mouse è necessario essere nella stessa area del paragrafo selezionato (per mantenere il :hover argomento vero), ma questo di solito è il caso comunque questo dovrebbe essere un bene – è la migliore che si vuole ottenere, se si desidera mantenere il vostro codice di markup è comunque:

    CSS:

    div[contenteditable="true"]:focus > p:hover {
       border: 2px solid red;
    }

    HTML:

    <div contenteditable="true">
       <p>The first paragraph</p>
       <p>The second paragraph</p>
    </div>

    jsFiddle qui.

    Se sei in grado di modificare il markup, è possibile utilizzare il seguente semplificata di selezione:

    CSS:

    p[contenteditable="true"]:focus {
       border: 2px solid red;
    }

    HTML:

    <div>
       <p contenteditable="true">The first paragraph</p>
       <p contenteditable="true">The second paragraph</p>
    </div>
    • Hm, sarebbe bello non avere inline abbraccia circa un paragrafo, anche se—almeno da un punto di verifica di vista.
    • Il secondo è quello che ho postato nella mia prima risposta, ma ha il problema che quando si preme Invio, si crea un nuovo <div> invece di un nuovo <p>, da qui il mio secondo tentativo.
    • Davvero? Non qui – jsfiddle.net/PPNE2/16
    • Bene, almeno in Chrome. In Firefox crea un <br> che è bene.

Lascia un commento