HTML适用于不可编辑的岛屿

时间:2013-01-30 23:05:00

标签: html contenteditable

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

Document-template是一个普通的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>元素的片段副本会从剪贴板内容中删除该输入,因此进一步粘贴操作会插入所有内容,但不会输入。
  • GC - 在<input>产生奇怪结果(bug)后立即点击{BACKSPACE}

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

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

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

还有其他想法吗?

6 个答案:

答案 0 :(得分:21)

我是CKEditor开发人员。我们对嵌套的只读元素(即placeholder插件和我们目前正在处理的功能#9764)有一些经验,我没有好消息。如果您希望具有一致的外观和感觉,则必须手动处理每个行为。没有技巧可以修复浏览器。

,许多事情(就像GC上的输入一样发生​​了奇怪的事情)似乎是无法解决的。

答案 1 :(得分:11)

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

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

您可以在http://jsfiddle.net/TwVzt/1/

尝试

但是这种方法并非没有问题(在我的情况下):没有办法使用 style DOM属性声明::before内联,所以应该在CSS中声明整个集合前期。 但是我拥有的一组合并代码非常大,在某些用例中甚至是未知的。叹息。

尽管有人会有更好的情况(已知的一组代码),但仍然把这个食谱放在这里。

答案 2 :(得分:3)

我知道它是一个旧线程,我遇到了类似的问题。在可编辑的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/

完成小提琴

答案 3 :(得分: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中按退格键时,它似乎刷新了,或者做了一个&#34;转到最后一页&#34;! 我把前两个undeditbles红色(留下最后一个黑色),这样你就可以看到会发生什么。我在Chrome和FF以及IE中的jsfiddle上测试它。所有人似乎都采取了正确行动,给予或采取退格问题。

我认为这是它运作的逻辑。 第一个Div是顶级父级,它是contenteditable =&#34; false&#34;。所以它下面的一切都应该是不可编辑的。除了其中的孩子们,这些孩子们已经跨越了contenteditble =&#34; true&#34;它们变得可编辑。所以你从父母那里继承,但是你可以像孩子一样覆盖。

我还将标签readonly =&#34; true&#34; UNSELECTABLE =&#34; ON&#34;因为我在某个地方读到了他们。它需要更多的测试!注意,我必须在跨度之外使用字体...否则它将无效。但在IE中,它完美无缺。无法描述的是我告诉他们的任何颜色,没有任何单一,dourble或三重点击将选择jsfiddle中的uneditbles! :-)对于Chrome单击没有做任何事情,双击选择了不可编辑,并使用退格它有点疯了!它似乎会转到上一页。随着FF的事情有点疯狂!双击选中不可编辑和可编辑之前!不知道为什么。

如果有人可以弄清楚并写下Chrome和FF的问题那就太棒了。如果双击或任何数量的快速点击都不适用于Chrome和FF,那将是一件好事。我想再次强调跨度......似乎必须在不可编辑的字体和字体之外......在跨度之外。

希望这一切都有意义。

答案 4 :(得分:1)

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

<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

答案 5 :(得分:-3)

对于IE,试试这个:

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

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