no message
This commit is contained in:
131
js/index.js
Normal file
131
js/index.js
Normal file
@@ -0,0 +1,131 @@
|
||||
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");
|
||||
Reference in New Issue
Block a user