【问题标题】:Prevent deletion of all <li> tags in a content editable <ul>防止删除内容可编辑 <ul> 中的所有 <li> 标记
【发布时间】:2014-06-12 15:43:02
【问题描述】:

当您在内容可编辑的&lt;ul&gt; 标记内一直退格到&lt;li&gt; 标记的开头时,所有剩余的&lt;li&gt; 标记都将被删除。

<ul contenteditable="true">
    <li>Hello</li>
    <li>World</li>
</ul>

jsfiddle:http://jsfiddle.net/8Q53V/

将光标放在世界中的“d”之后,然后退格一直到行首。当您再次按退格键时,它也会删除“Hello”列表项。如何防止这种行为?

更新:看起来这种行为只存在于 Chrome 中

【问题讨论】:

  • 不,我在 Firefox 中也会发生这种情况。
  • PS:以下解决方案都不适合我(2014 年夏季)。

标签: javascript html contenteditable


【解决方案1】:

这是我发现的:

仅当父 ul 元素后面没有任何其他最小渲染空间为 1px x 1px 的元素时,Opera 和 Chrome 中的 contenteditable 列表的错误行为才会发生。元素的display 值无关紧要,只要它不为空或通过 CSS 设置了高度尺寸即可。

所以添加一个简单的&lt;div style="height: 1px;"&gt; 将回答您最直接的问题。

但是,在询问时,您无法在 HTML 中可靠地使用 contenteditable 列表。

这个问题引起了我的兴趣,我在 Moz FF 29-30、Opera 21、Google Chrome 35 和 IE 11、Win 8.1 上对其进行了测试。我测试了 EnterBackspaceDelete 等简单键。

TL;DR:IE 11 完全搞砸了,如果 ul 后跟一个具有渲染大小的元素,Opera 和 Chrome 会做得很好,而 Moz FF 会插入一个奇怪的 &lt;br type="_moz"&gt;&lt;/br&gt;标签。您需要e.preventDefault()e.keyCode/charCodeSelectionRange JS API 来创建在所有浏览器中一致工作的自定义内容可编辑列表。但是,这些先决条件并不能在所有浏览器上始终如一地工作。最佳解决方案:使用现有的编辑器或一些不可见的文本输入进行输入。

这些是详细的陷阱:


点击 Enter 添加新的li 将添加以下标记:

  • Opera 和谷歌浏览器&lt;li&gt;&lt;br&gt;&lt;li&gt;
  • Moz FF&lt;li&gt;&lt;br type="_moz"&gt;&lt;/br&gt;
  • IE 11:如果活动的li 非空:&lt;li&gt;&lt;br&gt;&lt;/li&gt;,如果它是空的,IE 完全搞砸并插入一个p,然后在它后面复制一个空的&lt;ul contenteditable=""&gt; ,里面只有一个&lt;br&gt; 标签。这个空的ul 将被添加到 原始元素之后的元素(如果有)之后。

点击 Backspace 删除 li:not(:first-child) 将执行以下操作:

  • Opera 和谷歌浏览器:如果ul 后面没有带有渲染大小的元素,则所有li 将被删除。如果是,则会发生预期的行为。 (删除了一个li)。
  • Moz FF:出现预期行为(删除了一个 li)。但是,Moz FF 在删除 li 后会将光标移出 contenteditable 区域。
  • IE 11:与点击 Enter 时的行为相同。

点击Backspace来删除第一个li应该不惜一切代价阻止

对于每个测试的浏览器,这都会破坏列表布局。所有新的 Enter 命中都会生成 div 作为列表的直接子级。


点击 Delete 来删除后续的li 在所有经过测试的浏览器中都能正常工作。后面的li会被移除,里面的任何内容都会转移到当前的li


在空的li 中输入第一个字母将执行以下操作:

  • Opera、IE11 和谷歌浏览器:这封信被打印出来了。自动插入的&lt;br&gt; 标记被删除。
  • Moz FF:字母被打印出来。自定义 &lt;br type="_moz"&gt; 标记删除。

删除空li 中的唯一字母将执行以下操作:

  • Opera、IE11 和 Google Chrome:自动插入另一个 &lt;br&gt; 标签。
  • Moz FF:没什么。自定义 &lt;br type="_moz"&gt; 仍然存在。

小提琴:http://jsfiddle.net/8Q53V/8/(第一个 ul 是自定义编码行为,不完美,第二个 ul 是标准的)

【讨论】:

  • 1px 高度的 div 为我修复了这个错误。我对此感到非常困惑,非常感谢您的帮助和彻底的回应。
【解决方案2】:

您需要在每个li 标签上使用contenteditable

Demo

如果您不想自己分配属性,您可以使用 Javascript setAttribute() 来解决这个问题 - (您已在问题中标记了 Javascript,所以我假设您对 Javascript 持开放态度解决方案)

var elm = document.querySelectorAll('ul li');
for (var i=0; i < elm.length; i++) {
    elm[i].setAttribute("contenteditable", "true");
}

Demo(使用 Javascript 分配属性)

请注意这里,querySelectorAll() 中使用的选择器过于笼统,会匹配文档中的所有ul 元素,因此如果您想让一组特定的li 元素可编辑,而不是将classid 分配给您的ul 元素并适当地定义一个唯一的选择器。

如果您想要多个 ul li 可编辑,最好定义 class 而不是 id 因为 id 必须是唯一的...所以定义唯一会很麻烦每次您希望一组li 可编辑时。

【讨论】:

  • 这确实阻止了我看到的删除行为,但它也阻止了只删除一个 li,或按 Enter 键添加另一个 li。我正在寻找的是你会在所见即所得编辑器中找到的行为。
  • @tilleryj WYSIWYG 编辑器确实会删除 li 如果您按下退格按钮.. :) 如果您想附加 li 而不是使用按钮处理程序在单击该按钮时附加 li 跨度>
  • 我知道他们会这样做,但他们不会删除所有 li 项目,这就是这个示例所发生的情况。
  • @tilleryj 正如我所说,保持这样并添加一个按钮以添加li并删除li
  • 我想要的行为与您在所见即所得编辑器中看到的完全匹配,例如向 gmail 邮件添加项目符号列表。有一个添加/删除按钮是行不通的。
猜你喜欢
  • 2023-03-31
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多