2010-03-14 18 views
51

Este es mi código:¿Cómo puedo hacer que un elemento div sea editable (como un área de texto cuando hago clic en él)?

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

Respuesta

128

Vamos a trabajar a través de él.

No se puede hacer un div editable. No hay tal cosa como un div editable, al menos por ahora. Entonces, el problema es descubrir qué usar para editar. Un textarea funciona perfectamente. Entonces, la idea es obtener de algún modo un área de texto donde actualmente se encuentra el div.

La pregunta es cómo y de dónde obtenemos el área de texto. Hay varias maneras, pero una de ellas es la creación de un área de texto de forma dinámica sobre la marcha:

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

y reemplazarlo con el div:

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

El área de texto es en su lugar ahora. Pero está vacío y acabamos de reemplazar el div y lo perdimos todo. Entonces, debemos preservar el texto del div de alguna manera. Una forma de hacerlo es copiar el texto/html dentro de la div antes de reemplazarlo:

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

Una vez que tenemos el código HTML de la div, podemos poblar el área de texto y segura reemplazar el div con el área de texto. Y establece el foco dentro del área de texto ya que el usuario puede querer comenzar a editar. Combinando todo el trabajo hasta este punto, obtenemos:

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

Es funcional, pero no pasa nada cuando un usuario hace clic en un div porque no hicimos ningún evento configuración. Vamos a conectar los eventos. Cuando el usuario hace clic en cualquier div $("div").click(..), creamos un controlador de clics y hacemos todo lo anterior.

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

Esto es bueno, pero querría una manera de conseguir la espalda div cuando un usuario hace clic o se sale del área de texto. Hay un evento blur para controles de formulario que se desencadena cuando un usuario deja el control. Esto se puede usar para detectar cuándo un usuario abandona el área de texto y reemplazar el div. Hacemos exactamente lo inverso esta vez. Preserve el valor de textarea, cree un div dinámico, configure su html y reemplace el área de texto.

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

Todo está bien, excepto que este nuevo div ya no se convertirá en un área de texto al hacer clic. Este es un div recién creado, y tendremos que configurar el evento click nuevamente. Ya tenemos todo el código, pero mejor que repetirlo dos veces, es mejor hacer una función.

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

Como toda la operación es bidireccional reversible, necesitaremos hacer lo mismo para el área de texto. Vamos a convertir eso en una función también.

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

cableado hasta todo junto, que tiene 2 funciones, divClicked, editableTextBlurred y la línea de abajo desencadena todo:

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

Pedido este código en http://jsfiddle.net/GeJkU/. Esta no es la mejor manera de escribir divisiones editables de ninguna manera, sino solo una forma de comenzar y abordar la solución paso a paso. Honestamente, he aprendido tanto como usted al escribir este largo artículo. ¡Firmando, adios!

+3

Hay varios otros plugins existentes del editor in situ para jQuery que figuran en este hilo - http://stackoverflow.com/questions/708801/whats-the-best-edit-in -place-plugin-for-jquery. 'Editable' y' Jeditable' como Sarfaraz ya mencioné son algunos de los buenos, pero no sé qué tiene la edición en contexto tiene algo que ver con Star Wars: D – Anurag

+8

buen tutorial. La gente aprenderá de esto. Gracias. – Cheeso

+24

contenteditable = "true" * does * allow this capability. IE ha admitido desde 5.5 y HTML5 proporciona esto –

7

Use contenteditable="true" atributos para la división.

69

Para una div, puede utilizar este atributo HTML para hacerla editable:

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

Más información aquí: http://html5demos.com/contenteditable

Espero que esto ayude.

+3

El div ya no se comporta como div normal cuando contenteditable = "verdadero" con respecto a los enlaces que se vuelven inactivos. – dansalmo

+0

El método para que los enlaces permanezcan activos se muestra aquí: http://stackoverflow.com/questions/12059211/how-to-make-clickable-anchor-in-contenteditable-div – dansalmo

2

contenteditable tiene algunos defectos graves. Lo más condenatorio en mi opinión es la incompatibilidad entre navegadores en el uso de Enter. Vea esto article para una descripción. En Firefox, al hacer clic en Enter para un retorno de carro, se crea un nuevo párrafo, con un doble espacio efectivo en cada línea que no es lo suficientemente larga como para envolver. Muy feo.

+0

Esto no responde a la pregunta del OP. Esto debería ser un comentario en su lugar. –

4

Para aquellos que buscan para una versión on(), esto se basa en la respuesta de Anurag.

Si, por algún motivo, deseaba quitar el evento de clic del texto editable (por ejemplo, para ver versiones de contenido editables y no editables), podría aplicar $(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>

Cuestiones relacionadas