const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch } = Vue; createApp({ setup() { let titleLength = ref(200); let title = ref("发"); let info = ref({ anonymity: 0, }); const titleTextarea = ref(null); const adjustTextareaHeight = () => { nextTick(() => { const textarea = titleTextarea.value; if (textarea) { textarea.style.height = "auto"; textarea.style.height = textarea.scrollHeight + "px"; } }); }; watch(title, () => { adjustTextareaHeight(); }); const editorRef = ref(null); onMounted(() => { document.addEventListener("selectionchange", getFocusedNodeName); }); // 获取当前焦点所在的节点名称(仅在.editor内) const getFocusedNodeName = () => { const selection = window.getSelection(); if (!selection.rangeCount) return null; lastSelection = selection.getRangeAt(0); // 获取焦点所在的节点 let focusedNode = selection.focusNode; // 如果是文本节点,取其父元素 if (focusedNode.nodeType === Node.TEXT_NODE) { focusedNode = focusedNode.parentNode; } // 检查节点是否在.editor容器内 const isInEditor = editorRef.value.contains(focusedNode); if (!isInEditor) return null; if (focusedNode.tagName?.toLowerCase() == "h2") isPTitle.value = true; else isPTitle.value = false; }; const isPTitle = ref(false); let lastSelection = null; const onEditorInput = () => { const selection = window.getSelection(); if (selection.rangeCount > 0) { lastSelection = selection.getRangeAt(0); updatePTitleStatus(); } }; const paragraphTitle = () => { editorRef.value.focus(); if (!lastSelection) return; const selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(lastSelection); const focusNode = lastSelection.startContainer; document.execCommand("formatBlock", false, focusNode?.parentNode?.tagName == "H2" ? "P" : "H2"); }; const updatePTitleStatus = () => { if (lastSelection) { const node = lastSelection.commonAncestorContainer; isPTitle.value = node.nodeName === "H2" || (node.nodeType === Node.TEXT_NODE && node.parentNode?.nodeName === "H2"); } }; const insertImage = () => { const input = document.createElement("input"); input.type = "file"; input.accept = "image/*"; input.onchange = (e) => { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = (e) => { // 创建图片元素 const img = document.createElement("img"); img.src = e.target.result; img.alt = "用户上传图片"; // 确保编辑器获得焦点 editorRef.value.focus(); // 获取选择对象 const selection = window.getSelection(); // 如果有选择范围,在选择范围插入图片 console.log("rangeCount", selection.rangeCount); if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); range.deleteContents(); // 清除当前选择内容 range.insertNode(img); // 插入图片 // 将光标移动到图片后面 range.setStartAfter(img); range.setEndAfter(img); selection.removeAllRanges(); selection.addRange(range); } else { // 如果没有选择范围,直接追加到编辑器末尾 editorRef.value.appendChild(img); } }; reader.readAsDataURL(file); }; input.click(); }; return { editorRef, info, title, titleLength, titleTextarea, adjustTextareaHeight, isPTitle, paragraphTitle, insertImage, onEditorInput }; }, }).mount("#appIndex");