Javascript 如何使 div 元素可编辑(就像单击时的 textarea 一样)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2441565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:21:35  来源:igfitidea点击:

How do I make a div element editable (like a textarea when I click it)?

javascriptjquery

提问by zjm1126

This is my 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>

Thanks

谢谢

回答by Anurag

Let's work through it.

让我们解决它。

You can't make a div editable. There's no such thing as an editable div, at least for now. So the problem is finding out what to use for editing instead. A textarea works perfectly. So the idea is to somehow get a textarea where the div currently sits.

您不能使 div 可编辑。至少目前没有可编辑的 div 之类的东西。所以问题是找出用于编辑的内容。一个 textarea 工作得很好。所以这个想法是以某种方式获得一个 div 当前所在的文本区域。

The question is how and from where do we get the textarea. There are various ways, but one of them is to dynamically create a textarea on the fly:

问题是我们如何以及从哪里获得 textarea。有多种方法,但其中一种方法是动态创建一个文本区域:

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

and replace it with the div:

并将其替换为 div:

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

The textarea is in place now. But it is empty and we have just replaced the div and lost everything. So we need to preserve the text of the div somehow. One way is to copy the text/html inside the div before replacing it:

textarea 现在就位。但它是空的,我们刚刚替换了 div 并丢失了所有内容。所以我们需要以某种方式保留 div 的文本。一种方法是在替换之前复制 div 中的 text/html:

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

Once we have the html from the div, we can populate the textarea and safely replace the div with the textarea. And set the focus inside the textarea as the user might want to start editing. Combining all the work upto this point, we get:

一旦我们从 div 中获得了 html,我们就可以填充 textarea 并安全地用 textarea 替换 div。并在 textarea 内设置焦点,因为用户可能想要开始编辑。结合到目前为止的所有工作,我们得到:

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

It's functional but nothing happens when a user clicks a div because we didn't setup any events. Let's wire up the events. When the user clicks any div $("div").click(..), we create a click handler, and do all of the above.

它是有功能的,但是当用户单击 div 时没有任何反应,因为我们没有设置任何事件。让我们把事件联系起来。当用户单击任何 div 时$("div").click(..),我们创建一个单击处理程序,并执行上述所有操作。

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

This is good, but we'd want a way to get our div back when a user clicks out or leaves the textarea. There is a blurevent for form controls that is triggered when a user leaves the control. That can be used to detect when a user leaves the textarea, and replace back the div. We do the exact reverse this time. Preserve the value of textarea, create a dynamic div, set it's html, and replace out the textarea.

这很好,但我们想要一种在用户点击或离开 textarea 时恢复我们的 div 的方法。blur当用户离开控件时会触发表单控件的事件。这可用于检测用户何时离开 textarea,并替换回 div。这次我们完全相反。保留textarea的值,创建一个动态div,设置为html,替换掉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);
});

Everything is great, except that this new div will no longer convert into a textarea on click. This is a newly created div, and we'll have to setup the clickevent again. We already have the entire code, but better than repeating it twice, it's better to make a function out of it.

一切都很好,除了这个新的 div 将不再在点击时转换为 textarea。这是一个新创建的 div,我们必须click再次设置该事件。我们已经有了完整的代码,但比重复两次要好,最好是用它来制作一个函数。

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

Since the whole operation is two-way reversible, we'll need to do the same for the textarea. Let's convert that into a function too.

由于整个操作是双向可逆的,我们需要对 textarea 执行相同的操作。让我们也把它转换成一个函数。

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


Wiring up everything together, we have 2 functions, divClicked, editableTextBlurredand the line below triggers everything:

将所有内容连接在一起,我们有 2 个函数,divClickededitableTextBlurred下面的行触发了所有内容:

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

Checkout this code at http://jsfiddle.net/GeJkU/. This is not the best way of writing editable divs by any means, but just one way to start and approach the solution step by step. Honestly I have learnt just as much as you in writing this long piece. Signing off, adios!

http://jsfiddle.net/GeJkU/查看此代码。无论如何,这都不是编写可编辑 div 的最佳方式,而只是一种开始和逐步解决解决方案的方式。老实说,在写这篇长篇文章时,我和你学到的一样多。注销,再见!

回答by Nathan

To make a <div>(or any element for that matter) editable you can use the contenteditableHTML attribute.

要使<div>(或任何与此相关的元素)可编辑,您可以使用contenteditableHTML 属性。

For example:

例如:

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

More info here: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable

更多信息在这里:https: //developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable

回答by Devendar Rao

Use contenteditable="true"attributes for the division.

使用contenteditable="true"划分的属性。

回答by zevero

Based on the answer of Anurag I wrote a small jquery plugin:

根据 Anurag 的回答,我写了一个小的 jquery 插件:

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

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

which allows you to make all 'div.myDiv' elements editable:

它允许您使所有 'div.myDiv' 元素可编辑:

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

回答by user1063287

For those looking for an on()version, this is based on Anurag's answer.

对于那些寻找on()版本的人,这是基于 Anurag 的回答。

If, for some reason, you wanted to take the click event off the editable text input (eg for viewing editable and non editable versions of content), you could later apply $(document).off("click", ".editable_text");.

如果出于某种原因,您想从可编辑文本输入中移除 click 事件(例如,为了查看内容的可编辑和不可编辑版本),您可以稍后申请$(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>

回答by ross.bendigo

contenteditablehas some grave defects. The most damning in my view, is cross browser incompatability on Enter use. See this articlefor a description. In Firefox clicking Enter for a carriage return creates a new paragraph, effectively double spacing every line that isn't long enough to wrap. Very ugly.

contenteditable有一些严重的缺陷。在我看来,最糟糕的是 Enter 使用时跨浏览器不兼容。有关说明,请参阅此文章。在 Firefox 中单击 Enter 回车会创建一个新段落,有效地将每行不够长的行间距加倍以换行。十分难看。

回答by Vipin Pandey

can you try this one

你能试试这个吗

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

回答by Paul Chris Jones

Here's a simple solution:

这是一个简单的解决方案:

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

Working example at https://jsfiddle.net/pgdqhacj/2/. The only downside is that you have to double click to edit the text, not single click.

https://jsfiddle.net/pgdqhacj/2/ 上的工作示例。唯一的缺点是您必须双击才能编辑文本,而不是单击。