37

我有一种基于浏览器的所见即所得编辑器,用户可以在其中编辑文档模板。

文档模板是一个带有一些特殊“合并代码占位符”的普通 html。通过将这些占位符替换为来自 DB 的数据,此类模板得到“实例化”。这给出了最终文档 - 模板的一个实例。

我目前的方法如下所示:

<div contenteditable>
  Sample template with <input type=button class="mergecode" value="MergeCode1">.
</div>

(在线示例:http: //jsfiddle.net/tFBKN/

在这种情况下,输入是不可编辑的,并且表现为一个实心块——这正是我所需要的。用户可以通过单击 DEL 或 BACKSPACE 作为任何其他字符等来删除此类合并代码。通过为此类 input.mergecode 设置适当的 CSS,我能够实现我想要的外观。

但是通过这种方法,我在三个不同的 UA 中遇到了三个不同的问题:

  • IE - CSS{ font:inherit }在那里根本不起作用,所以如果输入<b>像这里一样在里面,<b><input value="test"></b>它不会继承任何字体样式。
  • FF - 包含<input>元素的片段副本会从剪贴板内容中删除该输入,因此进一步的粘贴操作会插入所有内容,但不插入输入。
  • <input>GC - 在产生奇怪的结果后立即点击 {BACKSPACE} (错误

所以我正在寻找其他关于如何在 HTML 中表示不可编辑的内联块类似“岛”的想法。

到目前为止我尝试过的其他方法:

  • <span contenteditable="false">MergeCode1</span>- 它不起作用,因为大多数 UA 从选择中删除了此类节点。因此,不可能在包含此类跨度的选择之上应用<b>或应用。<i>

还有其他想法吗?

4

6 回答 6

26

我是 CKEditor 开发人员。我们对嵌套只读元素(即placeholder插件和我们目前正在开发的功能#9764)有一些经验,但我没有好消息。如果你想拥有一致的外观和感觉,你必须手动处理每一个行为。没有任何技巧可以修复浏览器。许多事情(比如在 GC 输入周围发生的奇怪事情)似乎是无法解决的。

于 2013-02-04T08:59:23.803 回答
15

还有一个看起来很有希望的想法:

要使用空跨度::before { content:"caption"; },应该产生在 DOM 中表示为内部没有插入符号位置的节点的不可编辑块。

你可以在这里试试http://jsfiddle.net/TwVzt/1/

但是这种方法并非没有问题(在我的例子中):没有办法::before使用样式DOM 属性声明内联,因此应该在 CSS 中预先声明整个集合。但是我拥有的一组合并代码非常大,在某些用例中甚至是完全未知的。叹。

不过,如果有人有更好的情况(已知的代码集),请把这个食谱放在这里。

于 2013-02-02T03:04:06.363 回答
4

我知道它是一个旧线程,我遇到了类似的问题。只需要几个不可编辑的跨度在可编辑的 div 中。最终实现了一个像...一样的HACK-AROUND

$('#testDiv').on('keydown', function(e) { 
    var targetNode = getSelectionStart();
    if(targetNode != undefined && targetNode.nodeType === 1 && targetNode.nodeName == 'SPAN')    
    {
      var nodeHtmlString = targetNode.outerHTML;

      if(~nodeHtmlString.indexOf("nonEditable"))
      {
        e.preventDefault();
        e.stopPropagation();
      }
    }
});

function getSelectionStart() {
 var node = document.getSelection().anchorNode;
 return (node.nodeType == 3 ? node.parentNode : node);
}

在https://jsfiddle.net/fxmb3nL6/20/完成小提琴

于 2015-12-29T21:55:05.983 回答
2

下面的解决方案 - 有一个小警告。但首先——你们太棒了!
我不是 JS 或 HTML 专家,但我也不知道 jsfiddle.net。因此,阅读您的评论以及其他在线搜索,以及对 jsfiddle 的一些测试,我创建了以下有效的代码。

<pre><code>
<div contenteditable="false" class="editor" readonly="true" UNSELECTABLE="ON">
    Sample template with <span class="mergecode test1" />.
    <span contenteditable> editable </span>
    <font color=red><span UNSELECTABLE="ON" contenteditable="false" readonly="true"
     UNSELECTABLE="ON">  uneditable1 </span></font>
    <span contenteditable> editable2 </span>
    <font color=red><span contenteditable=false readonly="true" UNSELECTABLE="ON"> uneditable3</span></font>  
    <span contenteditable> editable4 </span>
    <span contenteditable="false" readonly="true" UNSELECTABLE="ON"> uneditable5 </span>
< /div>
</code></pre>

如果你把它放到 chrome 上的 jsfiddle 中,你会发现它在 chrome 中工作(以及 IE 和 FF,但有点不同),但似乎有一个小警告。

需要注意的是您的键绑定对 Backspace 的作用!就我而言,当我选择一个不可编辑的短语并在 chrome 中按退格键时,它似乎会刷新,或者执行“转到最后一页”!我将前两个 undeditbles 设为红色(留下最后一个黑色),以便您可以看到会发生什么。我在 Chrome、FF 和 IE 中的 jsfiddle 上对其进行了测试。一切似乎都采取了正确的行动,给予或接受退格问题。

我认为这是它如何工作的逻辑。 第一个 Div 是顶级父级,它是 contenteditable="false"。所以它下面的所有东西都应该是不可编辑的。除了其中具有跨度 contenteditble="true" 的孩子之外,它们变得可编辑。所以你从你的父母那里继承,但是你可以作为一个孩子覆盖。

我还把标签 readonly="true" UNSELECTABLE="ON" 因为我在某个地方读到过它们。而且还需要更多的测试!!!请注意,我必须将 Font... 放在跨度之外,否则它将不起作用。但在 IE 中它工作得很好。uneditables 是我告诉他们的任何颜色,没有多少单次,双击或三次单击会选择 jsfiddle 中的 uneditbles !!!:-) 对于 Chrome,单击什么也没做,双击选择了不可编辑的,并且使用退格键它有点疯狂!似乎会转到上一页。FF的事情有点疯狂!双击选中不可编辑的和之前的可编辑的!不知道为什么。

如果有人能弄清楚并写下 Chrome 和 FF 的问题,那就太好了。如果在 Chrome 和 FF 中双击或任意数量的快速点击也不起作用,那就太好了。我想再次强调跨度......似乎必须在不可编辑和字体旁边......在跨度之外。

希望这一切都有意义。

于 2014-09-25T23:28:07.480 回答
0

这是我在项目中使用的解决方案:

<div>
  <span contenteditable>Editable text</span> <span> - Non editable text</span>
</div>

用对应的 CSS 看结果:

div {
  border: 1px solid black;
  display: inline-block;
  max-width: 200px;
}

结果如下:http ://www.cssdesk.com/rULJM

于 2019-10-27T16:38:22.463 回答
-3

对于 IE,试试这个:

<span contenteditable="true">Uneditable</span>

注意 contenteditable 属性的反向值!它违背了所有常识,但它确实有效——至少在 IE8 和 IE9 中是这样。您可以移动和复制/粘贴这个不可编辑的元素。然而,它远非完美。例如,如果您将包含不可编辑元素的区域加粗,这也会感染不可编辑元素的内容。因此,您可能必须使用一些脚本来保持元素的完整性。还设置 contenteditable="true" 将使用调整大小手柄装饰不可编辑的元素。您可以通过设置 unselectable="on" 再次关闭它们,但这将防止对象被拖动。同样,您可能不得不依赖恢复宽度和高度的脚本。

于 2013-01-31T18:32:29.420 回答