当前我遇到的问题是 使用div
contentEditable
想实现话题功能,但是当我#之后光标会默认走前面,所以如何让光标跟我所打字的来正确显示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HashtagDiv</title>
<style>
.hashtag {
color: red;
/* 设置井号的高亮颜色 */
}
</style>
</head>
<body>
<div id="editableDiv" contenteditable="true">在这里输入内容...</div>
<div>
Current position: <span id="current-position">-</button>
</div>
<script>
let isComposing = false;
// 获取可编辑div的引用
var editableDiv = document.getElementById('editableDiv');
const currentPosEle = document.getElementById('current-position');
// 添加input事件监听器,以便实时读取内容
editableDiv.addEventListener('input', handleInput);
editableDiv.addEventListener('compositionstart', handleCompositionStart);
editableDiv.addEventListener('compositionend', handleCompositionEnd);
// document.addEventListener('selectionchange', handleSelectionChange);
function handleSelectionChange() {
if (document.activeElement !== editableDiv) {
return;
}
const selection = window.getSelection();
console.log('selection', selection)
const range = selection.getRangeAt(0);
const clonedRange = range.cloneRange();
clonedRange.selectNodeContents(editableDiv);
clonedRange.setEnd(range.endContainer, range.endOffset);
currentPosEle.innerHTML = clonedRange.toString().length;
};
// 添加paste事件监听器,以便处理粘贴
editableDiv.addEventListener('paste', function (e) {
// 阻止默认粘贴行为
e.preventDefault();
// 获取粘贴的纯文本内容
var pastedText = (e.originalEvent || e).clipboardData.getData('text/plain');
// 在粘贴的文本中插入换行符
pastedText = pastedText.replace(/\s+/g, '\n');
// 将处理后的文本插入可编辑div
document.execCommand('insertText', false, pastedText);
// 处理插入后的内容
handleInput();
});
function handleInput(e) {
if (!isComposing) {
var content = editableDiv.textContent;
var selection = window.getSelection();
var startPosition = selection.focusOffset;
console.log('selection',selection)
console.log('startPosition',startPosition)
// 清空可编辑div的内容
editableDiv.innerHTML = '';
// 处理每个字符
for (let i = 0; i < content.length; i++) {
var char = content[i];
// 如果是#,则处理直到空白字符
if (char === '#') {
var hashtag = char;
i++;
while (i < content.length && content[i] !== ' ' && content[i] !== '#' && content[i] !== '\n') {
hashtag += content[i];
i++;
}
// 创建span元素并设置样式和内容
var span = document.createElement('span');
span.className = 'hashtag';
span.innerText = hashtag;
console.log('hashtag', hashtag)
// 将span元素添加到可编辑div中
editableDiv.appendChild(span);
// 因为while循环内i会自增,这里需要回退一步
i--;
} else {
// 如果不是#,直接添加字符
var currentText = editableDiv.innerHTML;
var newText = currentText + char;
editableDiv.innerHTML = newText;
}
}
// 设置新的光标位置
selection.collapse(editableDiv.firstChild, startPosition);
}
}
// 处理中文输入法的组合开始事件
function handleCompositionStart() {
console.log("正在组织...");
isComposing = true;
};
// 处理中文输入法的组合结束事件
function handleCompositionEnd() {
console.log("结束组织...");
isComposing = false;
handleInput()
};
</script>
</body>
</html>