我在插入符号位置拆分标签内容时遇到一些问题。我可以获得分割索引以及分割后插入符号位置的标签内容。我面临的问题如下所示。
<html>
<div contenteditable="true">
<strong><em> Suppose this is the content inside tag </em></strong>
</div>
</html>
我已将光标设置在“内容”和“内部”一词之间。如果我现在按下一个按钮,它应该执行如下操作:
<html>
<div contenteditable="true">
<strong>
<em> Suppose this is the content </em>
</strong>
"""the cursor will be here"""
<strong>
<em>inside tag </em>
</strong>
</div>
</html>
首先获取选区,找到光标位置,将其定位在可编辑的
div
中,然后在该位置拆分innerHTML
。
接下来,从
target
元素开始(被单击的最里面的元素,不一定与添加单击处理程序的元素相同),使用 do {} while ()
循环和 parentNode
属性来创建一个嵌套标签数组。
将嵌套标签数组转换为字符串,首先是结束标签,然后是开放标签。该数组迭代两次,一次按照初始顺序,然后在颠倒顺序后进行第二次。
有了“之前”的 HTML,标签关闭然后打开字符串,以及“之后”的 HTML,然后将它们组合起来,最后更新可编辑的
div
。
document.querySelector("div").addEventListener("click", function({target, currentTarget}) {
if (target !== currentTarget) {
let sel = window.getSelection(),
elem = target, // target is clicked element
ao = sel.anchorOffset, // get cursor postion in target
an = sel.anchorNode,
txt = an.textContent,
ctxt = currentTarget.innerHTML, // currentTarget is event listener element
cao = ctxt.indexOf(txt) + ao, // get cursor position in currentTarget
bef = ctxt.substring(0, cao),
aft = ctxt.substring(cao, ctxt.length),
tags = [];
// get all nested tags
do {
tags.push(elem.tagName);
elem = (undefined === elem) ?
target.parentNode : elem.parentNode;
} while (elem !== currentTarget);
// build new HTML with close and open tags inserted at cursor
let ntxt = bef; // start with HTML before cursor
// convert tag array to string of close tags
ntxt += tags.reduce((prev, tag) => prev + '</' + tag + ">", "");
// reverse tag array
ntxt += tags.reverse()
// then convert to open tags
.reduce((prev, tag) => prev + '<' + tag + ">", "");
// end with HTML after cursor
ntxt += aft;
currentTarget.innerHTML = ntxt;
sel.collapse(sel.focusNode, 2); // frankly, I don't know why "2" works here :S
// resulting (encoded) HTML contents of div
console.log(currentTarget.innerHTML);
}
});
<div contenteditable="true">
<strong><em> Suppose this <span>is the</span> content inside tag </em></strong>
</div>
您的代码工作完美,只有当 div 包含换行符 (
) 并且插入符号位于换行符的开头时才会失败。如何修改才能处理这种情况?
document.querySelector("div").addEventListener("click", function({target, currentTarget}) {
if (target !== currentTarget) {
let sel = window.getSelection(),
elem = target, // target is clicked element
ao = sel.anchorOffset, // get cursor postion in target
an = sel.anchorNode,
txt = an.textContent,
ctxt = currentTarget.innerHTML, // currentTarget is event listener element
cao = ctxt.indexOf(txt) + ao, // get cursor position in currentTarget
bef = ctxt.substring(0, cao),
aft = ctxt.substring(cao, ctxt.length),
tags = [];
// get all nested tags
do {
tags.push(elem.tagName);
elem = (undefined === elem) ?
target.parentNode : elem.parentNode;
} while (elem !== currentTarget);
// build new HTML with close and open tags inserted at cursor
let ntxt = bef; // start with HTML before cursor
// convert tag array to string of close tags
ntxt += tags.reduce((prev, tag) => prev + '</' + tag + ">", "");
// reverse tag array
ntxt += tags.reverse()
// then convert to open tags
.reduce((prev, tag) => prev + '<' + tag + ">", "");
// end with HTML after cursor
ntxt += aft;
currentTarget.innerHTML = ntxt;
sel.collapse(sel.focusNode, 2); // frankly, I don't know why "2" works here :S
// resulting (encoded) HTML contents of div
console.log(currentTarget.innerHTML);
}
});
<div contenteditable="true">
<strong><em> Suppose this <span>is the</span> content<br><br><br><br> inside tag </em></strong>
</div>