结构重构
This commit is contained in:
parent
04c3f57218
commit
5bb61de760
69
cursor.js
69
cursor.js
@ -53,65 +53,52 @@ export class Cursor {
|
|||||||
|
|
||||||
// 获取当前光标的矩形位置
|
// 获取当前光标的矩形位置
|
||||||
getBoundingClientRect() {
|
getBoundingClientRect() {
|
||||||
this.updateRange()
|
this.range.setStart(this.targetNode, this.insertIndex)
|
||||||
|
this.range.setEnd(this.targetNode, this.insertIndex)
|
||||||
return this.range.getBoundingClientRect()
|
return this.range.getBoundingClientRect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新光标位置
|
// 更新光标位置
|
||||||
updatePosition(rect) {
|
updatePosition({ left, top }) {
|
||||||
if (!rect) {
|
this.cursorElement.style.left = `${left}px`
|
||||||
this.hide()
|
this.cursorElement.style.top = `${top}px`
|
||||||
return
|
|
||||||
}
|
|
||||||
this.cursorElement.style.left = `${rect.left}px`
|
|
||||||
this.cursorElement.style.top = `${rect.top}px`
|
|
||||||
this.cursorElement.style.display = "block"
|
this.cursorElement.style.display = "block"
|
||||||
}
|
}
|
||||||
|
|
||||||
// 隐藏光标
|
|
||||||
hide() {
|
|
||||||
this.cursorElement.style.display = "none"
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除光标元素
|
// 移除光标元素
|
||||||
remove() {
|
remove() {
|
||||||
this.cursorElement.remove()
|
this.cursorElement.remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
move(key) {
|
oninput({ value }) {
|
||||||
// 获取目标节点的上下兄弟节点(li元素)
|
const text = this.targetNode.textContent
|
||||||
const children = Array.from(this.targetNode.parentNode.parentNode.children)
|
const left = text.slice(0, this.insertIndex)
|
||||||
const siblings = children.filter(node => {
|
const right = text.slice(this.insertIndex)
|
||||||
return node !== this.targetNode && node.nodeType === Node.ELEMENT_NODE
|
this.insertIndex += value.length
|
||||||
}).map(item => {
|
this.targetNode.textContent = left + value + right
|
||||||
return Array.from(item.childNodes).find(node => node.nodeType === Node.TEXT_NODE)
|
this.updatePosition(this.getBoundingClientRect())
|
||||||
})
|
}
|
||||||
const currentIndex = siblings.indexOf(this.targetNode)
|
|
||||||
|
|
||||||
if (key === "ArrowUp" && currentIndex > 0) {
|
onkeydown({ key }) {
|
||||||
const prevSibling = siblings[currentIndex - 1]
|
if (key === "ArrowUp" && this.targetNode.parentNode.previousElementSibling) {
|
||||||
const index = Math.max(0, Math.min(prevSibling.textContent.length, this.insertIndex))
|
// 先取兄弟元素的最后一个子元素, 没有则取兄弟元素, 没有则向上回溯
|
||||||
this.setTarget(prevSibling, index) // 光标在上一个兄弟元素的起始位置
|
this.targetNode = Array.from(this.targetNode.parentNode.previousElementSibling.childNodes).find(node => node.nodeType === Node.TEXT_NODE)
|
||||||
return
|
this.insertIndex = Math.max(0, Math.min(this.targetNode.textContent.length, this.insertIndex))
|
||||||
|
this.updatePosition(this.getBoundingClientRect())
|
||||||
}
|
}
|
||||||
|
if (key === "ArrowDown" && this.targetNode.parentNode.nextElementSibling) {
|
||||||
if (key === "ArrowDown" && currentIndex >= 0 && currentIndex < siblings.length - 1) {
|
// 先取当前子元素, 没有则取下一个兄弟元素, 没有则向上回溯
|
||||||
const nextSibling = siblings[currentIndex + 1]
|
this.targetNode = Array.from(this.targetNode.parentNode.nextElementSibling.childNodes).find(node => node.nodeType === Node.TEXT_NODE)
|
||||||
const index = Math.max(0, Math.min(nextSibling.textContent.length, this.insertIndex))
|
this.insertIndex = Math.max(0, Math.min(this.targetNode.textContent.length, this.insertIndex))
|
||||||
this.setTarget(nextSibling, index) // 光标在下一个兄弟元素的起始位置
|
this.updatePosition(this.getBoundingClientRect())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
if (key === "ArrowLeft") {
|
||||||
if (key === "ArrowLeft" && this.insertIndex > 0) {
|
|
||||||
this.insertIndex = Math.max(0, Math.min(this.targetNode.textContent.length, this.insertIndex - 1))
|
this.insertIndex = Math.max(0, Math.min(this.targetNode.textContent.length, this.insertIndex - 1))
|
||||||
this.updateRange()
|
return this.updatePosition(this.getBoundingClientRect())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
if (key === "ArrowRight") {
|
||||||
if (key === "ArrowRight" && this.insertIndex < this.targetNode.textContent.length) {
|
|
||||||
this.insertIndex = Math.max(0, Math.min(this.targetNode.textContent.length, this.insertIndex + 1))
|
this.insertIndex = Math.max(0, Math.min(this.targetNode.textContent.length, this.insertIndex + 1))
|
||||||
this.updateRange()
|
return this.updatePosition(this.getBoundingClientRect())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
markdown.js
50
markdown.js
@ -33,49 +33,13 @@ document.body.appendChild(textarea)
|
|||||||
|
|
||||||
// 处理输入事件
|
// 处理输入事件
|
||||||
textarea.oninput = () => {
|
textarea.oninput = () => {
|
||||||
const inputText = textarea.value // 获取用户输入的文本
|
cursors.forEach(cursor => cursor.oninput(textarea))
|
||||||
if (!inputText) return
|
|
||||||
|
|
||||||
cursors.forEach(cursor => {
|
|
||||||
if (!cursor.targetNode || cursor.insertIndex === null) return
|
|
||||||
|
|
||||||
// 更新文本节点内容
|
|
||||||
cursor.targetNode.textContent =
|
|
||||||
cursor.targetNode.textContent.slice(0, cursor.insertIndex) +
|
|
||||||
inputText +
|
|
||||||
cursor.targetNode.textContent.slice(cursor.insertIndex)
|
|
||||||
|
|
||||||
// 更新插入位置
|
|
||||||
cursor.insertIndex += inputText.length
|
|
||||||
})
|
|
||||||
|
|
||||||
// 清空输入框
|
|
||||||
textarea.value = ""
|
textarea.value = ""
|
||||||
updateCursors()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理方向键移动插入点
|
// 处理方向键移动插入点
|
||||||
textarea.onkeydown = (event) => {
|
textarea.onkeydown = (event) => {
|
||||||
cursors.filter(cursor => cursor.targetNode && cursor.insertIndex !== null).forEach(cursor => {
|
cursors.forEach(cursor => cursor.onkeydown({ key: event.key }))
|
||||||
cursor.move(event.key)
|
|
||||||
updateCursors()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新所有光标的位置
|
|
||||||
const updateCursors = () => {
|
|
||||||
cursors.forEach(cursor => {
|
|
||||||
if (!cursor.targetNode || cursor.insertIndex === null) {
|
|
||||||
cursor.hide()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取插入点位置
|
|
||||||
const rect = cursor.getBoundingClientRect()
|
|
||||||
|
|
||||||
// 更新光标位置
|
|
||||||
cursor.updatePosition(rect)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染 Markdown 并监听点击事件
|
// 渲染 Markdown 并监听点击事件
|
||||||
@ -131,18 +95,10 @@ element.onclick = (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新光标位置
|
// 更新光标位置
|
||||||
updateCursors()
|
cursors.forEach(cursor => cursor.updatePosition(cursor.getBoundingClientRect()))
|
||||||
|
|
||||||
// 聚焦输入框
|
// 聚焦输入框
|
||||||
textarea.value = ""
|
textarea.value = ""
|
||||||
textarea.focus()
|
textarea.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按删除键移除光标
|
|
||||||
document.addEventListener('keydown', (event) => {
|
|
||||||
if (event.key === 'Delete' && cursors.length > 0) {
|
|
||||||
const cursorToRemove = cursors.pop() // 移除最后一个光标
|
|
||||||
cursorToRemove.remove() // 移除对应的光标元素
|
|
||||||
console.log("移除光标")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
Loading…
Reference in New Issue
Block a user