61 votes

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

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

Gracias

146voto

Anurag Points 66470

Essayons d'y arriver.

Vous ne pouvez pas rendre un div modifiable. Il n'existe pas de div modifiable, du moins pour l'instant. Le problème est donc de trouver quoi utiliser à la place pour l'édition. Un textarea fonctionne parfaitement. L'idée est donc d'obtenir une zone de texte là où se trouve actuellement la division.

La question est de savoir comment et d'où nous pouvons obtenir le textarea. Il existe plusieurs moyens, mais l'un d'entre eux consiste à 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 le div et nous avons tout perdu. Nous devons donc préserver le texte de la division d'une manière ou d'une autre. Une façon de le faire 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 html du div, nous pouvons remplir la zone de texte et remplacer en toute sécurité le div par la zone de texte. Et mettre le focus à l'intérieur de la zone de texte car l'utilisateur pourrait vouloir commencer à éditer. En combinant tout le travail effectué 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 une division, car nous n'avons pas configuré d'événements. Mettons en place les événements. Lorsque l'utilisateur clique sur un div $("div").click(..) nous créons un gestionnaire de clics, 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();
});

C'est bien, mais nous voulons un moyen de récupérer notre div lorsqu'un utilisateur clique pour sortir ou quitter la zone de texte. Il existe un blur pour les contrôles de formulaires qui est déclenché lorsqu'un utilisateur quitte le contrôle. Cela peut être utilisé pour détecter quand un utilisateur quitte le textarea, et replacer le div. Cette fois-ci, nous faisons exactement l'inverse. Nous conservons la valeur de textarea, créons un div dynamique, définissons son html, et remplaçons 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 parfait, sauf que ce nouveau div ne se convertira plus en textarea au clic. Il s'agit d'une div nouvellement créée, et nous devrons configurer l'attribut click événement à nouveau. Nous avons déjà le code complet, mais plutôt que de le répéter deux fois, il est préférable d'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-la également en fonction.

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

En reliant tout ensemble, nous avons 2 fonctions, divClicked , editableTextBlurred et la ligne ci-dessous déclenche tout :

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

Vérifiez ce code à http://jsfiddle.net/GeJkU/ . Ce n'est en aucun cas la meilleure façon d'écrire des divs modifiables, mais juste 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 texte. Je termine, adios !

3 votes

Il existe plusieurs autres plugins d'édition en place pour jQuery, énumérés dans ce fil de discussion. stackoverflow.com/questions/708801/ . Editable y Jeditable comme Sarfaraz l'a déjà mentionné, il y en a de bons, mais je ne sais pas ce que l'édition en place a à voir avec Star Wars :D

33 votes

Contenteditable="true" fait permettent cette capacité. IE le supporte depuis la version 5.5 et HTML5 le prévoit.

7 votes

Pourquoi devons-nous suivre tout cela ? Ne pouvons-nous pas rendre la division modifiable en utilisant l'attribut contenteditable="true". Je l'ai utilisé de nombreuses fois et je n'ai jamais rencontré de problèmes.

90voto

Nathan Points 4662

Pour faire un <div> (ou n'importe quel élément d'ailleurs) modifiable, vous pouvez utiliser la balise contenteditable Attribut HTML.

Par exemple :

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

Plus d'informations ici : https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable

3 votes

Le div ne se comporte plus comme un div normal lorsque contenteditable="true" en ce qui concerne les liens qui deviennent inactifs.

0 votes

La méthode pour que les liens restent actifs est présentée ici : stackoverflow.com/questions/12059211/

11voto

Devendar Rao Points 41

Utilisez contenteditable="true" attributs pour la division.

5voto

zevero Points 29

Sur la base de la réponse d'Anurag, j'ai écrit un petit plugin jquery :

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

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

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

4voto

ross.bendigo Points 21

contenteditable a de graves défauts. Le plus grave, à mon avis, est l'incompatibilité entre les navigateurs lors de l'utilisation de Enter. Voir ce qui suit article pour une description. Dans Firefox, le fait de cliquer sur Entrée pour un retour chariot crée un nouveau paragraphe, ce qui a pour effet de doubler l'espacement de chaque ligne qui n'est pas assez longue pour être enveloppée. C'est très laid.

4 votes

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X