我在HTML中有这个内容可编辑的div
<div contenteditable="true" id="TextOnlyPage"></div>
继承我的jquery代码
var rxp = new RegExp("(([0-9]+\.?[0-9]+)|([0-9]+))", "gm");
$('#TextOnlyPage').keyup(function(e){
if(e.keyCode == 13){
e.preventDefault();
$('#TextOnlyPage').children().each(function() {
if ( $(this).is("div") ) {
$(this).contents().unwrap();
}});
$('#TextOnlyPage').append("<br/>");
}
$('#TextOnlyPage').children().contents().unwrap();
var $this = $(this);
var content = $this.html();
$this.html(content.replace(rxp, "<span class='highlight'>$1</span>"));});
问题是插入位置,因为当它在string.replace方法中的数字周围应用span标记时,光标将转到内容可编辑div
的开头。当我按下回车键时,它也不能进入下一行。
我知道我可以通过range
和selection
个对象处理它,但无法找到有用的资源来了解这些对象的工作原理。
请为我提供这个问题的解决方案,如果是angularjs中的解决方案会更好,或者为我提供一个资源,我可以通过工作示例了解范围和选择对象。
答案 0 :(得分:1)
我遇到了与您前一段时间相同的问题,为了了解range
和selection
的工作原理,我建议您查看MDN文档Selection和{{3} }
检测contentEditable
div中的更改的一种可靠方法是事件input
。我在听keyUp
并阻止某些keyCode
的默认行为时发现的一个问题是它们很多,并且很难涵盖所有用例。
我更喜欢做的是处理正常事件,保存插入位置,获取文本值并替换需要突出显示的部分,然后再设置插入位置。
这是一个简单的例子
var contentEditable = document.querySelector('div[contenteditable]');
contentEditable.addEventListener('input', onInput);
var onInput = function(e) {
// this function will be called after the current call-stack
// is finished, at that time the user input will be inserted
// in the content editable
setTimeout(function() {
// save the caret position
var text = contentEditable.innerText;
// perform all your replacement on `text`
contentEditable.innerHTML = text;
// set the caret position back
}, 0);
}
我还编写了两个方便的方法getCaretOffsetWithin
和setCaretPositionWithin
来帮助操作插入符号,以便在处理后执行一些DOM操作并将插入符号重新定位到其初始值。
您可以在这个要点Range
上查看它们答案 1 :(得分:0)
以下是来自MDN的一些资源:Selection和Range。
我已经创建了这个JSFiddle to demonstrate re-positioning the caret。
它并不适用于所有情况(例如,在输入时,选择带有shift +箭头的范围......)但它应该已经给你一些想法。
以下是MDN关于创建选择的示例:
/* Select all STRONG elements in an HTML document */
var strongs = document.getElementsByTagName("strong");
var s = window.getSelection();
if(s.rangeCount > 0) s.removeAllRanges();
for(var i = 0; i < strongs.length; i++) {
var range = document.createRange();
range.selectNode(strongs[i]);
s.addRange(range);
}
作为旁注,与contentEditable
合作将来会带来更多麻烦,我建议尽力找到替代方案。另外,请务必注意我提供的链接中有限的浏览器支持警告。