2010-03-14 15 views
51

Questo è il mio codice:Come faccio a rendere modificabile un elemento div (come una textarea quando clicco su di esso)?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
    <head> 
     <meta name="viewport" content="width=device-width, user-scalable=no"> 
    </head> 
<body> 
     <style type="text/css" media="screen"> 

     </style> 

     <!--<div id="map_canvas" style="width: 500px; height: 300px;background:blue;"></div>--> 

     <div class=b style="width: 200px; height: 200px;background:pink;position:absolute;left:500px;top:100px;"></div> 
     <script src="jquery-1.4.2.js" type="text/javascript"></script> 
     <script src="jquery-ui-1.8rc3.custom.min.js" type="text/javascript"></script> 
     <script type="text/javascript" charset="utf-8"> 

     </script> 
    </body> 
</html> 

Grazie

risposta

128

Lavoriamo attraverso di essa.

Non è possibile modificare un div. Non esiste un div editabile, almeno per ora. Quindi il problema è scoprire cosa usare per l'editing. Una textarea funziona perfettamente. Quindi l'idea è di ottenere in qualche modo una textarea dove si trova attualmente il div.

La domanda è come e da dove si ottiene la textarea. Ci sono vari modi, ma uno di loro è quello di creare dinamicamente una textarea al volo:

var editableText = $("<textarea />"); 

e sostituirlo con il div:

$("#myDiv").replaceWith(editableText); 

La textarea è a posto ora. Ma è vuoto e abbiamo appena sostituito il div e perso tutto. Quindi abbiamo bisogno di preservare il testo del div in qualche modo. Un modo è quello di copiare il testo/html all'interno del div prima di sostituirla:

var divHtml = $("#myDiv").html(); // or text(), whatever suits. 

Una volta che abbiamo il codice HTML del div, siamo in grado di popolare il textarea e sicuro sostituire il div con la textarea. E imposta la messa a fuoco all'interno dell'area di testo poiché l'utente potrebbe voler iniziare a modificare. La combinazione di tutto il lavoro fino a questo punto, si ottiene:

// save the html within the div 
var divHtml = $("#myDiv").html(); 
// create a dynamic textarea 
var editableText = $("<textarea />"); 
// fill the textarea with the div's text 
editableText.val(divHtml); 
// replace the div with the textarea 
$("#myDiv").replaceWith(editableText); 
// editableText.focus(); 

E 'funzionale, ma non succede nulla quando un utente fa clic su un div perché non abbiamo messa a punto tutti gli eventi. Colleghiamo gli eventi. Quando l'utente fa clic su qualsiasi div $("div").click(..), creiamo un gestore di clic e facciamo tutto quanto sopra.

$("div").click(function() { 
    var divHtml = $(this).html(); // notice "this" instead of a specifiC#myDiv 
    var editableText = $("<textarea />"); 
    editableText.val(divHtml); 
    $(this).replaceWith(editableText); 
    editableText.focus(); 
}); 

Questo è un bene, ma ci vorrebbe un modo per ottenere la nostra schiena div quando un utente fa clic fuori o lascia la textarea. Esiste un evento blur per i controlli del modulo che viene attivato quando un utente lascia il controllo. Questo può essere usato per rilevare quando un utente lascia la textarea e rimpiazzare il div. Facciamo l'esatto contrario questa volta. Mantieni il valore di textarea, crea un div dinamico, imposta il suo html e sostituisci la textarea.

$(editableText).blur(function() { 
    // Preserve the value of textarea 
    var html = $(this).val(); 
    // create a dynamic div 
    var viewableText = $("<div>"); 
    // set it's html 
    viewableText.html(html); 
    // replace out the textarea 
    $(this).replaceWith(viewableText); 
}); 

Tutto è grande, tranne che questo nuovo div non verrà più convertito in un'area di testo al clic. Questo è un div appena creato e dovremo configurare nuovamente l'evento click. Abbiamo già l'intero codice, ma è meglio che ripeterlo due volte, è meglio farne una funzione.

function divClicked() { 
    var divHtml = $(this).html(); 
    var editableText = $("<textarea />"); 
    editableText.val(divHtml); 
    $(this).replaceWith(editableText); 
    editableText.focus(); 
    // setup the blur event for this new textarea 
    editableText.blur(editableTextBlurred); 
} 

Poiché l'intera operazione è reversibile a due vie, sarà necessario fare lo stesso per la textarea. Convertiamolo in una funzione.

function editableTextBlurred() { 
    var html = $(this).val(); 
    var viewableText = $("<div>"); 
    viewableText.html(html); 
    $(this).replaceWith(viewableText); 
    // setup the click event for this new div 
    $(viewableText).click(divClicked); 
} 

Cablaggio tutto insieme, abbiamo 2 funzioni, divClicked, editableTextBlurred e la linea sotto innesca tutto:

$("div").click(divClicked); 

Acquista questo codice a http://jsfiddle.net/GeJkU/. Questo non è il modo migliore di scrivere div modificabili con qualsiasi mezzo, ma solo un modo per iniziare e avvicinarsi alla soluzione passo dopo passo. Onestamente, ho imparato tanto quanto te nello scrivere questo lungo pezzo. Firma, Adios!

+3

Ci sono vari altri esistenti in-place plugin Editor per jQuery elencati in questa discussione - http://stackoverflow.com/questions/708801/whats-the-best-edit-in -posto-plugin-per-jQuery. 'Editable' e' Jeditable' come già detto da Sarfaraz sono alcuni di quelli buoni, ma non so cosa abbia il montaggio sul posto di qualcosa con Star Wars: D – Anurag

+8

buon tutorial. Le persone impareranno da questo. Grazie. – Cheeso

+24

contenteditable = "true" * fa * consente questa funzionalità. IE ha supportato dal 5.5 e HTML5 prevede questo –

7

Utilizzare gli attributi contenteditable="true" per la divisione.

69

Per un div, è possibile utilizzare questo attributo HTML per renderlo modificabile:

<div contenteditable="true">Anything inside this div will be editable!</div> 

Maggiori informazioni qui: http://html5demos.com/contenteditable

Spero che questo aiuti.

+3

Il div non si comporta più come un normale div quando contenteditable = "true" rispetto ai link che diventano inattivi. – dansalmo

+0

Il metodo per mantenere attivi i collegamenti è mostrato qui: http://stackoverflow.com/questions/12059211/how-to-make-clickable-anchor-in-contenteditable-div – dansalmo

2

contenteditable ha alcuni gravi difetti. Il più schiacciante a mio avviso, è l'incompatibilità cross browser su Enter use. Vedere questo article per una descrizione. In Firefox, facendo clic su Invio per un ritorno a capo, viene creato un nuovo paragrafo, con una doppia spaziatura efficace di ogni riga che non è sufficientemente lunga da avvolgere. Molto brutto.

+0

Questo non risponde alla domanda dell'OP. Questo dovrebbe essere un commento, invece. –

4

Per chi cerca per una versione on(), questa è basata sulla risposta di Anurag.

Se, per qualche motivo, si desidera escludere l'evento click dall'input di testo modificabile (ad esempio per visualizzare versioni modificabili e non modificabili del contenuto), è possibile applicare in seguito $(document).off("click", ".editable_text");.

$(document).on("click", ".editable_text", function() { 
 
    var original_text = $(this).text(); 
 
    var new_input = $("<input class=\"text_editor\"/>"); 
 
    new_input.val(original_text); 
 
    $(this).replaceWith(new_input); 
 
    new_input.focus(); 
 
}); 
 

 
$(document).on("blur", ".text_editor", function() { 
 
    var new_input = $(this).val(); 
 
    var updated_text = $("<span class=\"editable_text\">"); 
 
    updated_text.text(new_input); 
 
    $(this).replaceWith(updated_text); 
 
});
.text_editor { 
 
    border: none; 
 
    background: #ddd; 
 
    color: #000; 
 
    font-size: 14px; 
 
    font-family: arial; 
 
    width: 200px; 
 
    cursor: text; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<p><span class="editable_text">Here is my original text.</span> 
 
</p>

Problemi correlati