我的任务是将文本插入符设置为显示在contentEditable
div中的空span节点内。
以下内容在Firefox 3.6上没有任何问题:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="js/jquery-1.4.3.min.js">
</script>
<style>
#multiple {
border: 1px solid #ccc;
width: 800px;
min-height: 20px;
padding: 5px;
outline: none;
}
</style>
<script>
$(document).ready(function(){
var contentEditable = document.getElementById('multiple');
var lastItem = contentEditable.getElementsByTagName('span').item(2);
var selectElementText = function(el, win){
win = win || window;
var doc = win.document, sel, range;
if (win.getSelection && doc.createRange) {
range = doc.createRange();
range.selectNodeContents(el);
range.collapse(false);
sel = win.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
else
if (doc.body.createTextRange) {
range = doc.body.createTextRange();
range.moveToElementText(el);
range.select();
}
}
contentEditable.focus();
selectElementText(lastItem);
});
</script>
<title>Range Selection Tasks (Make Me Want to Cry)</title>
</head>
<body>
<div id="multiple" contentEditable="true">
<span style="color:red">First</span><span style="color:green">Second</span><span style="color:blue"></span>
</div>
</body>
</html>
...但是在Webkit和IE上,焦点设置为倒数第二个范围。不知道为什么。如果我在最后一个跨度内放置一个空格,那么它可以工作,但我得到一个单字符范围选择。
话虽如此,如果插入符号一开始就在最后一个节点中有空格是可以接受的。
对此的任何帮助将不胜感激。提前谢谢。
答案 0 :(得分:11)
将元素的innerHTML
设置为零宽度字符:
('element').innerHTML = 'ÈB';
现在carret可以去那里。
答案 1 :(得分:5)
IE的选择/范围模型基于文本内容的索引,忽略元素边界。我相信可能无法将输入焦点设置在没有文本的内联元素中。当然,在您的示例中,我无法通过单击或箭头键在最后一个元素内设置焦点。
如果将每个范围设置为display: block
,它几乎可以工作,尽管仍然存在一些非常奇怪的行为,这取决于父级中是否存在空白。黑客将显示内容与浮点,内联块和绝对位置等技巧内联,使IE将每个元素视为一个单独的编辑框。相对定位的块元素彼此相邻,但这可能是不切实际的。
如果它让你感觉更好,IE9最终修复了这种不愉快并采用标准范围模型。 (万岁!)
如果插入符号一开始就在最后一个节点中有空格是可以接受的。
我可能会这样做,然后,除非IE选择专家能想到更好的东西。 (打电话给蒂姆!)
答案 2 :(得分:2)
我找到了一个Webkit的解决方法,不知道是否有人之前发现了这个,而不是以编程方式附加零宽度空间,你可以在元素的后psuedo-selector中使用css3内容属性做同样的事情你想把插入符号放入。这样做的好处是多余的字符不会出现在DOM中,用户无法在它之间导航插入符号。所以基本上它不需要清理。
为了使其适用于内容可编辑元素的任何子元素,它将是这样的:
#mycontenteditableelement *:after {
content: '\200B';
}
我没有完全检查,但我怀疑这是一个完整的解决方法。
答案 3 :(得分:1)
聚会晚了一点,但是我使用了Unicode零宽度不间断空格(
)。然后,在用户输入发生后调用的事件上,删除零宽度无间断空格。
我在使用Unicode空间问题时遇到了很多问题,大多数是糟糕的UX。这样可以防止用户知道存在问题。
答案 4 :(得分:0)
将最小高度和最小宽度应用于内嵌块内部的元素可以某些好,但影响会产生意想不到的副作用:
#multiple * {
min-height: 1em;
}
span, b, strong, i, em, a, etc {
display: inline-block;
min-width: 1em;
background-color: hsla(0, 50%, 50%, .5); /* this is only a visual aid; discard @ will */
vertical-align: middle; /* so elements w/ inline-block align w/ text correctly */
}
你会发现仍然存在问题,但是如果你愿意为一小部分其他人牺牲一些问题,这可能会有一些好处。
答案 5 :(得分:0)
对我来说,设置contenteditable div的内容为<br>
。我尝试将其设置为nbsp;
但在开始编辑之前在div中创建了额外的字符空间。
希望这有帮助。