web-dev-qa-db-fra.com

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

Ceci est mon code:

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

52
zjm1126

Travaillons à travers cela.

Vous ne pouvez pas rendre une div modifiable. Il n’existe pas de div éditable, du moins pour le moment. Le problème est donc de savoir quoi utiliser pour l'édition à la place. Un textarea fonctionne parfaitement. Donc, l’idée est d’obtenir en quelque sorte une zone de texte où la div se trouve actuellement.

La question est de savoir comment et d'où obtenons-nous la zone de texte. Il y a différentes façons, mais l'une d'entre elles 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 il est vide et nous venons de remplacer la div et avons tout perdu. Nous devons donc préserver le texte de la div en quelque sorte. Une solution consiste à copier le texte/html dans la 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 renseigner la zone de texte et remplacer celle-ci en toute sécurité par la zone de texte. Et définissez le focus dans la zone de texte de manière à ce que l'utilisateur puisse commencer à éditer. En combinant tout le travail 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();

C'est fonctionnel, mais rien ne se passe lorsqu'un utilisateur clique sur une div car nous n'avons pas configuré d'événements. Câblons les événements. Lorsque l'utilisateur clique sur une div $("div").click(..), nous créons un gestionnaire de clics et procédons comme suit.

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

C'est bien, mais nous voudrions un moyen de récupérer notre div lorsqu'un utilisateur clique ou quitte la zone de texte. Un événement blur pour les contrôles de formulaire est déclenché lorsqu'un utilisateur quitte le contrôle. Cela peut être utilisé pour détecter le moment où un utilisateur quitte la zone de texte et remplacer la div. Nous faisons l'inverse exact cette fois-ci. Conservez la valeur de textarea, créez un div dynamique, définissez son code html et remplacez le 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);
});

Tout est génial, sauf que cette nouvelle div ne sera plus convertie en zone de texte au clic. Il s'agit d'un div nouvellement créé, et nous devrons configurer à nouveau l'événement click. Nous avons déjà l'intégralité du code, mais mieux que de le répéter deux fois, il vaut mieux en faire une fonction.

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

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

Tout relier 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 modifiables, mais une façon de commencer et d'aborder la solution étape par étape. Honnêtement, j'ai appris autant que vous en écrivant ce long article. Déconnexion, adios!

133
Anurag

Pour un div, vous pouvez utiliser cet attribut HTML pour le rendre éditable:

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

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

J'espère que cela t'aides.

73
Nathan

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

7
Devendar Rao

Basé sur la réponse de Anurag, j’ai écrit un petit plugin jquery:

https://github.com/zevero/jquery-html-editable

ce qui vous permet de rendre tous les éléments 'div.myDiv' modifiables:

$('body').html_editable('div.myDiv');
5
zevero

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

Si, pour une raison quelconque, vous souhaitez supprimer l’événement click de la saisie de texte modifiable (par exemple, pour afficher les versions de contenu modifiables et non modifiables), vous pouvez appliquer ultérieurement $(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>

4
user1063287

contenteditable a quelques défauts graves. Le plus accablant à mon avis est l’incompatibilité entre les navigateurs en mode Enter. Voir cet article pour une description. Dans Firefox, cliquer sur Entrée pour un retour à la ligne crée un nouveau paragraphe, doublant ainsi efficacement chaque ligne qui n'est pas assez longue pour être renvoyée à la ligne. Très laid.

3
ross.bendigo

pouvez-vous essayer celui-ci 

 <!DOCTYPE html>
    <html>
    <body>

    <div id="myP">This is a paragraph. Click the button to make me editable.</div>

    <button onclick="myFunction()">Try it</button>

    <p id="demo"></p>

    <script>
    function myFunction() {
        document.getElementById("myP").contentEditable = true;
        document.getElementById("demo").innerHTML = "The p element above is now editable. Try to change its text.";
    }
    </script>

    </body>
    </html>
0
Vipin Pandey

Voici une solution simple:

$('div').click(function(e){
    this.contentEditable = 'true';
});

Exemple de travail à https://jsfiddle.net/pgdqhacj/2/ . Le seul inconvénient est que vous devez double-cliquer pour éditer le texte, pas un simple clic.

0
Paul Jones