【发布时间】:2021-09-13 22:31:01
【问题描述】:
我希望实现的行为将在用户键入消息时将用户键入的每个单词包装在
中。他们正在输入的父 div 具有 contenteditable="true"。一个复杂的因素是,对于这个用例,一个“单词” div 可能包含两个单词(想象一个名称将被视为一个“单词”,因此例如
Bob Smith
可能会出现)。这意味着当用户按下空格键并将 (" ") 拆分为数组以构建 div.word DOM 元素时,我不能只获取所有 textContent。
我在想,当用户按下空格键时,我可以获取 contenteditable div 的所有子节点并循环遍历它们以检查哪个是 textNode,哪个不是(即,已经包含在 div.word 中的单词)。然后对于文本节点,我可以构建一个 div.word DOM 元素并将所有这些附加到 contenteditable div。
我希望这很清楚。这就是我所处的位置:
<div id="editor" contenteditable></div>
#editor {
border: 1px solid #333;
padding: 10px;
}
#editor .word {
background: yellow;
display: inline-block;
}
const editorElement = document.getElementById('editor');
function handleSpacebarPress() {
// Get all editor child nodes
let editorChildNodes = [...editor.childNodes];
// Clear editor of all child nodes
editor.innerHTML = '';
editorChildNodes.forEach(node => {
// If node is a text node (not a div.word element)
if (node.nodeType === 3) {
// Create div.word
let wordDiv = document.createElement('div');
wordDiv.className = 'word';
wordDiv.textContent = node.textContent;
editor.appendChild(wordDiv);
}
// Else node is already a div.word element
else {
editor.appendChild(node);
}
});
// Return caret to end of editor
const editorLength = editor.childNodes.length;
const lastNode = editor.childNodes[editorLength - 1]; // Last editor node
const range = document.createRange();
const selection = window.getSelection();
range.setStart(lastNode, 1);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
}
editorElement.addEventListener('keydown', e => {
if (e.code === 'Space') {
handleSpacebarPress();
}
});
您可以在 jsfiddle here 上查看此内容。
现在似乎只是将所有单词直接放入一个 div.word 元素中,而我似乎无法为每个单词创建一个新元素。
有什么想法吗?
【问题讨论】:
-
当您“将插入符号返回到编辑器末尾”时,光标将位于最后一个单词 div 内。在编辑器中最后生成的 div 之后放置一个空格,然后设置光标。否则,您正在对最后一个单词 div 进行内容编辑。
-
我尝试添加 editor.appendChild(document.createTextNode(' '));就在“返回插入符号...”评论之前。这就是您在最后生成的 div 之后放置一个空格的意思吗?
标签: javascript