javascript - 如何将元素(在可编辑的div内)从光标位置分成两部分,然后在它之间插入一个自定义元素?
问题描述
我需要将光标位置的元素(在可编辑的 div 内)分成两部分,然后在它之间插入一个自定义元素。
修改前:(竖线“|”表示光标的位置。我用“|”表示光标所在的位置给你。但实际上,这个字符在文本中是不存在的。)
<div contenteditable="true">
<span style="font-size='14px'">this is | a test</span>
<p>other paragraphs .....</p>
</div>
进行更改后:
<div contenteditable="true">
<span style="font-size:'14px'">this is </span><span style="font-size:'16px'">new text|</span><span style="font-size:'14px'">a test</span>
<p>other paragraphs .....</p>
</div>
需要注意的是,进行更改后,光标必须插入到新的自定义元素中最后一个字母之后。
我试了一下,但是:
let sel = window.getSelection();
let range = sel.getRangeAt(0);
if (range.startContainer.parentNode.nodeName === 'SPAN') {
let sel, range, cloneNode1, cloneNode2, cloneText, allContents, contentsBeforeCursor, contentsAfterCursor, newNode
sel = window.getSelection();
range = document.createRange();
range.selectNode(sel.anchorNode);
cloneNode1 = range.commonAncestorContainer.cloneNode();
cloneNode2 = cloneNode1.cloneNode();
cloneText = range.cloneContents();
allContents = cloneText.textContent;
contentsBeforeCursor = allContents.substring(0, sel.anchorOffset);
contentsAfterCursor = allContents.substring(sel.anchorOffset, allContents.length);
cloneNode1.textContent = contentsBeforeCursor
cloneNode2.textContent = contentsAfterCursor
newNode = document.createElement('SPAN');
for (let i = 0; i < cloneNode1.attributes.length; i++) {
let attr = cloneNode1.attributes.item(i);
newNode.setAttribute(attr.nodeName, attr.nodeValue);
}
newNode.style.fontSize = '13px';
range.selectNode(sel.anchorNode.parentNode);
range.deleteContents();
range.insertNode(cloneNode1)
range.insertNode(newNode)
range.insertNode(cloneNode2)
newNode.focuse();
https://jsfiddle.net/nekooee/0h8zcfv4/43/
这是为了更改 SPAN 中间的字体。CKEditor 也是如此。
解决方案
就像我在评论中说的,这不是你想要的吗?
它甚至具有与您相同的 HTML 标记。
此外,您的 HTML 标记全错:
<span style="font-size='14px'">
应该:
<span style="font-size:14px">
您的示例中的每个样式属性也是如此。
function pasteHtmlAtCaret(html, selectPastedContent) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// only relatively recently standardized and is not supported in
// some browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
var firstNode = frag.firstChild;
range.insertNode(frag);
// Preserve the selection
/*
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
if (selectPastedContent) {
range.setStartBefore(firstNode);
} else {
range.collapse(true);
}
sel.removeAllRanges();
sel.addRange(range);
}*/
}
} else if ( (sel = document.selection) && sel.type != "Control") {
// IE < 9
var originalRange = sel.createRange();
originalRange.collapse(true);
sel.createRange().pasteHTML(html);
if (selectPastedContent) {
range = sel.createRange();
range.setEndPoint("StartToStart", originalRange);
range.select();
}
}
}
function test()
{
var input = '<span style="font-size:25px;color:red"> new text </span>';
//document.getElementById("myDiv").focus();
pasteHtmlAtCaret(input, false);
}
<div contenteditable="true">
<span style="font-size:14px">this is a test</span>
<p>other paragraphs .....</p>
<button type="button" onclick="test()" unselectable="on">Test</button>
</div>
推荐阅读
- rxjs - 在switchMap中操作时保持状态
- python - 使用python selenium单击类中的span元素
- c++ - 如何引用模板化基类的嵌套类型
- javascript - React 组件不会在第一次状态更新时重新渲染
- sql - 数据库中已经有一个名为“#BaseData”的对象
- excel - 有没有一种方法可以获取和组合数百张 Excel 表格的所有内容、元数据并粘贴到一个中?
- c++ - 用 C++ 设计和实现一个接口:如果我这样做我该死,如果我不这样做我该死
- python - 使用散景小部件中的新值进行交互式 python 绘图
- python - django sessions remember me
- html - 可滚动元素的顶部被隐藏