难以置信的

时间:2016-08-27 23:29:06

标签: javascript html contenteditable

当我在contenteditable div元素中创建一个有序列表时,如下例所示,我无法访问Firefox中的空列表项。在Chrome中,它在功能方面起作用,但仍有一个小的缩进问题。

问题

考虑以下示例。 (也可用JSFIDDLE)在这里,您可以看到我使用JavaScript创建了有序列表。每一行都成为一个列表项。第二个列表项为空,因为该行为空。我也使用自定义列表样式。

CSS

#editable ol {
    list-style-type: none;
}
#editable ol > li {
    counter-increment: customlistcounter;
}
#editable ol > li::before {
    content: counter(customlistcounter) " ";
}
#editable ol:first-child {
    counter-reset: customlistcounter;
}

HTML

<div class="editable" id="editable" contenteditable="true">first

third</div>

的JavaScript

var editable = document.getElementById("editable");
editable.innerHTML = '<ol><li>'+editable.textContent.split("\n").join('</li><li>')+"</li></ol>";

行为

在Firefox 48.0中

如果我将光标设置到第一行的末尾并使用键盘将光标向右移动,则光标会立即跳转到第三行。同样,如果将光标设置到第三行的开头并按左箭头键,光标将跳转到第一行。此外,我无法使用鼠标将光标设置为第二行。

在Chromium 52.0

与Firefox相比,我可以使用鼠标和键盘将光标设置为第二行。但是,光标插入符号出现在项目标记的前面而不是它后面。当我输入一个字符时,光标会跳到右侧。即使我再次删除该字符,它也会保持在右侧。

预期行为

当我复制并使用JavaScript生成的HTML代码时(例如使用Firebug),删除JavaScript部分和自定义列表样式我最终使用以下代码(也可用JSFIDDLE):

<div class="editable" id="editable" contenteditable="true"><ol><li>first</li><li></li><li>third</li></ol></div>

适用于Firefox和Chrome。您可以将光标设置为第二行,光标插入符号显示在右侧位置。 CSS部分有其公平的问题。如果你不丢弃它,你可以通过鼠标和第一行的箭头键到达第二行,但不能从第三行到达。而你无法通过键盘从第二行到达第一行。

问题

为什么使用第一种方法不起作用?它不应该导致完全相同的行为?这是一个错误,未定义的行为还是我在这里遗漏了什么? 另外,我该如何解决这个问题?我必须使用JavaScript在contenteditable div元素中创建内容。另外我想使用自定义列表样式。但是我希望我的第二个例子中的行为能够编辑空的第二行。

更新

我第二次想到了这件事。由于纯HTML / CSS版本运行得更好,它可能是一个解析器问题。所以我在创建列表项时尝试了不同的方法。万一你好奇,以下也不起作用。这种行为与我的第一次尝试完全一样。

var editable = document.getElementById("editable");
var lines = editable.textContent.split("\n");

while(editable.firstChild) {
    editable.removeChild(editable.firstChild);
}
var ol = document.createElement("ol");

for(var i = 0; i < lines.length; i++)
{
    var li = document.createElement("li");
    var textnode = document.createTextNode(lines[i]);
    li.appendChild(textnode);
    ol.appendChild(li)
}
editable.appendChild(ol);

1 个答案:

答案 0 :(得分:0)

一种解决方法是在每个空行中添加一个不可见的字符。类似于var editable = document.getElementById("editable"); editable.innerHTML = '<ol><li>'+editable.textContent.split("\n").join('</li><li>').split('<li></li>').join('<li>&zwnj;</li>')+"</li></ol>";

&zwnj;

缺点是用户在某些情况下必须按两次箭头键,因为Refused to display 'https://mobile.facebook.com/v2.7/dialog/oauth?...' in a frame because it set 'X-Frame-Options' to 'DENY'. 被视为普通字符。如果还需要修复此问题,可以通过监听按键事件并手动纠正插入符号的位置来实现此目的。