有没有办法使文本区域部分可编辑?(仅使部分文本可编辑)

IT技术 javascript jquery textarea
2021-02-21 10:57:17

我刚刚遇到了一种情况,在这种情况下,只有文本区域的一部分(以前加载了文本)可编辑而其他部分不可编辑(可以说是“变灰”),这将是一个优雅的解决方案。

一般来说,这完全可以通过使用 javascript 来实现吗?

我会使用jQuery。

6个回答

你可以这样做(只是一个概述的想法,没有代码):

设计一个与整个文本匹配的正则表达式。不可修改部分使用固定字符串,可修改部分使用固定字符串[\s\S]*?使用^$来锚定您的正则表达式。

/^This is fixed text\. Now something editable:[\s\S]*?Now fixed again\.$/

现在对keyup事件做出react,可能还有其他事件(如paste)。

对于每个相关事件,检查正则表达式是否仍然匹配。

如果没有,请取消活动。

实际上,这应该停止对正则表达式中文字部分的修改,从而使文本的某些部分变为只读。

不要忘记在表单发布后在服务器端测试字符串 - 永远不要相信客户端不能发送无效值。


编辑

您可以使用正则表达式引用函数从字符串动态构建该正则表达式,这应该会为您省去很多麻烦。

function regexQuote(s) { return s.replace(/[\[\]^$*+?{}.|\\]/g, "\\$&") }

用法

var re = new Regex(
  "^" + 
  [regexQuote(fixedPart1), regexQuote(fixedPart2)].join("[\\s\\S].*?")
   + "$"
);
这是使用“输入”事件的实现(遗憾的是 IE9 不完全支持):jsfiddle.net/un6c950h使用“keyup”和“paste”事件会引入值改变然后恢复的跳跃行为:jsfiddle.net/un6c950h/2
2021-05-03 10:57:17
@Peter 我们如何添加一个或多个常量值(例如 {Jack} 先生喜欢 {红色} 颜色 {fruits})
2021-05-10 10:57:17

如果您使用纯 textarea 元素,您将无法设置所需内容的样式(基于该内容是否可编辑)。充其量您可以检查您的用户尝试更改的内容是否在黑名单或白名单中,然后相应地停止编辑。您还可以提供一些视觉反馈,例如警告消息“您不能这样做”。

我的建议是利用contenteditable属性,这可能需要更多的时间来设计样式,但从长远来看会让你有更大的灵活性。

您可以将 div 元素的样式设置为与您所需的 textarea 非常相似,然后在其中使用可编辑的跨度来设置是否可以编辑特定的文本块。然后,您可以使用 JavaScript 命令(请参阅上面的链接)或使用“保存”按钮来检索此内容,将其设置为实际 textarea(您可以隐藏)的值,然后照常发布您的页面。

使用以下代码作为粗略示例。

<div id="editable-content">
    <span id="block1" class="editable" contenteditable="true">This is some editable content which will </span>
    <span id="block2" class="non-editable">quickly be followed by some non-editable content</span>
</div>
<div style="display: none;">
    <textarea id="PostedContent"></textarea>
</div>
<div>
    <input id="save-page" type="submit" value="Save Page" />
</div>

<script type="text/javascript">
    $(function () {
        $('#save-page').click(function () {
            $('#PostedContent').val($('#editable-content').text());
        });
    });
</script>
哇。这是天才!我发现了这个:hallojs.org/demo/markdown,结合你使用 contenteditable<span>标签的方法,它工作得很好。我以为我将不得不花一到五天时间来开发我需要的 HTML 文本编辑器,但看起来只花了 5 分钟 :)
2021-05-03 10:57:17
+1 这是一个不错的方法。但是,由于表单发布完全依赖于 JavaScript,我建议也contenteditable通过 JavaScript 进行设置此外,我不建议弹出消息框。闪烁背景颜色(或类似的东西)的干扰要小得多。
2021-05-06 10:57:17
这很好,但它在 IE9 中有一种奇怪的行为,即写一些东西然后删除它(有时下面的文字会返回,有时它会留在原处,在中间留下这个尴尬的空白)
2021-05-10 10:57:17

搜索后发现很难使文本区域部分可编辑

这是我用于此要求的代码

input
{
  width:100%;
  border:0px solid;
  outline:none
}

 
<!DOCTYPE html>
   <html>     
<div style="padding: 2px;border:1px solid #ccc;width: 82%;max-height:100px;min-height: 51px;overflow:auto;outline: none;resize: both;" contenteditable="true" unselectable="on">    
    

  <input placeholder="enter prefix..." value="editable postfix..." ></input>
  <div id='unEditable' style="background-color:yellow;width: fit-content;padding-left:10px;padding-right:10px;border-radius:10px;height: fit-content;" contenteditable="false" unselectable="off" onkeyup="" >
         fixed content non-editable
        
   </div>
  <input placeholder="enter postfix..." value="editable prefix..." style='width:97%'></input>
    
 </div>
</html>

嗯,你可以做这样的事情。这段代码效率很低,我只是想概述一下这个概念。

JS:

$(function () {
            var tb = $("#t").get(0);
            $("#t").keydown(function (event) {
                var start = tb.selectionStart;
                var end = tb.selectionEnd;
                var reg = new RegExp("(@{.+?})", "g");
                var amatch = null;
                while ((amatch = reg.exec(tb.value)) != null) {
                    var thisMatchStart = amatch.index;
                    var thisMatchEnd = amatch.index + amatch[0].length;
                    if (start <= thisMatchStart && end > thisMatchStart) {
                        event.preventDefault();
                        return false;
                    }
                    else if (start > thisMatchStart && start < thisMatchEnd) {
                        event.preventDefault();
                        return false;
                    }
                }
            });
        });

HTML

<textarea id="t" rows=5 cols="80">Hello this is a test @{stuff} 

        this part is editable @{other stuff}     

    </textarea>

这使用了您对“标记”的概念。一般的想法是说好的,用户尝试编辑的文本范围是否在我们的标记之一内?显然,每次按下一个键时使用正则表达式并不是确定这一点的最佳方法,我没有忽略箭头键等,但这给了你一个大致的想法。

有趣的想法,但遗憾的是,必须统一处理文本区域内的文本,即您不能禁用文本区域内容的一部分。

但是,您确实有选择。如果您可以识别需要禁用的文本,则可以将其添加为 DOM 元素(即 div),然后以暗示它位于文本区域内的方式放置它。

您可以通过使文本区域变大并使用 position:relative/absolute 样式将 div 移动到文本区域上来暗示此 div 位于文本区域内。或者,您可以移除文本区域上的边框并将其放在一个容器上,该容器还包含带有“禁用”文本的 div。