2010-03-14 24 views
51

Ceci est mon code:Comment rendre un élément div modifiable (comme une zone de texte lorsque je clique dessus)?

<!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> 

Merci

Répondre

128

Travaillons à travers elle.

Vous ne pouvez pas rendre un div modifiable. Il n'y a pas de div modifiable, du moins pour l'instant. Donc, le problème est de savoir ce qu'il faut utiliser pour l'édition à la place. Une zone de texte fonctionne parfaitement. Donc l'idée est d'obtenir en quelque sorte une zone de texte où se trouve actuellement la div.

La question est de savoir comment et d'où nous obtenons le textarea. Il existe différentes façons, mais l'un d'entre eux est de créer dynamiquement une zone de texte à la volée:

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

et le remplacer par le div:

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

Le textarea est en place maintenant. Mais c'est vide et nous venons de remplacer la div et de tout perdre. Nous devons donc préserver le texte de la div en quelque sorte. Une façon est de copier le texte/html à l'intérieur du div avant de le remplacer:

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

Une fois que nous avons le code html de la div, nous pouvons remplir la zone de texte et le remplacer en toute sécurité le div avec le textarea. Et définissez le focus dans la zone de texte car l'utilisateur peut vouloir commencer à modifier. La combinaison de tous les travaux jusqu'à ce point, nous obtenons:

// 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(); 

Il est fonctionnel, mais rien ne se passe lorsqu'un utilisateur clique sur un div parce que nous ne l'avons pas la configuration des événements. Câblons les événements. Lorsque l'utilisateur clique sur un div $("div").click(..), nous créons un gestionnaire de clic, et faisons tout ce qui précède.

$("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(); 
}); 

Ce qui est bon, mais nous voudrions un moyen d'obtenir le dos div lorsqu'un utilisateur clique sur ou quitte la zone de texte. Il existe un événement blur pour les contrôles de formulaire qui est déclenché lorsqu'un utilisateur quitte le contrôle. Cela peut être utilisé pour détecter quand un utilisateur quitte la zone de texte, et replacer la div. Nous faisons exactement l'inverse cette fois-ci. Conservez la valeur de textarea, créez un div dynamique, définissez-le en HTML et remplacez la zone de texte.

$(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); 
}); 

Tout est génial, sauf que cette nouvelle div ne sera plus convertie en zone de texte sur click. C'est un div nouvellement créé, et nous devrons configurer à nouveau l'événement click. Nous avons déjà tout le code, mais mieux que de le répéter deux fois, il vaut mieux en faire une fonction. Comme toute l'opération est réversible dans les deux sens, nous devrons faire de même pour la zone de texte. Convertissons cela en une fonction aussi.

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); 
} 

Câblage tout ensemble, nous avons 2 fonctions, divClicked, editableTextBlurred et la ligne ci-dessous déclenche tout:

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

Commander ce code à http://jsfiddle.net/GeJkU/. Ce n'est pas la meilleure façon d'écrire des divs éditables par n'importe quel moyen, mais juste une façon de commencer et d'aborder la solution étape par étape. Honnêtement, j'ai appris tout autant que toi à écrire cette longue pièce. Déconnexion, adios!

+3

Il existe plusieurs autres plugins existants éditeur en place pour jQuery énumérés dans ce fil - http://stackoverflow.com/questions/708801/whats-the-best-edit-in -place-plugin-pour-jquery. «Editable» et «Jeditable» comme Sarfaraz déjà mentionné sont quelques-uns des bons, mais je ne sais pas ce que l'édition sur place a quelque chose à voir avec Star Wars: D – Anurag

+8

bon tutoriel. Les gens vont apprendre de cela. Merci. – Cheeso

+24

contenteditable = "true" * autorise * cette fonctionnalité. IE a pris en charge depuis 5.5 et HTML5 fournit pour cela –

7

Utilisez les attributs contenteditable="true" pour la division.

69

Pour div, vous pouvez utiliser cet attribut HTML pour le rendre modifiable:

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

Plus d'infos ici: http://html5demos.com/contenteditable

Hope this helps.

+3

La div ne se comporte plus comme la div normale quand contenteditable = "true" par rapport aux liens qui deviennent inactifs. – dansalmo

+0

La méthode pour que les liens restent actifs est affichée ici: http://stackoverflow.com/questions/12059211/how-to-make-clickable-anchor-in-contenteditable-div – dansalmo

2

contenteditable a quelques défauts graves. Le plus accablant à mon avis, c'est l'incompatibilité entre les navigateurs sur Enter use. Voir ce article pour une description. Dans Firefox, lorsque vous cliquez sur Entrée pour un retour chariot, un nouveau paragraphe est créé, ce qui équivaut à doubler chaque ligne qui n'est pas assez longue pour être renvoyée. Très laid.

+0

Cela ne répond pas à la question de l'OP. Cela devrait être un commentaire à la place. –

4

Pour ceux qui cherchent pour une version on(), ceci est basé sur la réponse d'Anurag.

Si, pour une raison quelconque, vous vouliez supprimer l'événement click de la saisie de texte modifiable (par exemple pour afficher des versions éditables et non éditables du contenu), vous pouvez appliquer par la suite $(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>

Questions connexes