feat(编辑器): 优化移动端编辑器交互体验

- 修复键盘弹出时底部操作栏遮挡问题,添加固定定位效果
- 改进光标定位逻辑,适配不同输入场景
- 增加内容预填充功能,便于测试和演示
- 调整底部间距和动画高度,适配不同设备
- 添加vConsole调试工具便于移动端调试
This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-10-11 18:56:00 +08:00
parent ad975d5c25
commit 6f93f8cf17
5 changed files with 383 additions and 154 deletions

159
2.html Normal file
View File

@@ -0,0 +1,159 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>可点击其他元素+保持光标不丢</title>
<style>
.container {
max-width: 600px;
margin: 50px auto;
padding: 20px;
}
/* 可编辑区域 */
.edit-area {
min-height: 100px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 16px;
outline: none;
margin-bottom: 20px;
}
/* 其他可点击元素(都能正常触发点击逻辑) */
.other-btn {
margin: 0 8px 10px 0;
padding: 8px 16px;
border: none;
border-radius: 4px;
background: #4285f4;
color: white;
font-size: 14px;
cursor: pointer;
}
.link {
color: #4285f4;
text-decoration: underline;
cursor: pointer;
margin-right: 15px;
}
.popup-box {
margin: 15px 0;
padding: 15px;
border: 1px solid #eee;
border-radius: 8px;
background: #f9f9f9;
cursor: pointer;
}
#popup {
display: none;
margin: 10px 0;
padding: 10px;
border: 1px solid #ff4444;
background: #fff0f0;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="container">
<!-- 核心:可编辑区域 -->
<div class="edit-area" contenteditable="true" id="editArea">
点击这里输入...点击下方按钮/链接/区域,它们能正常工作,光标也不会消失
</div>
<!-- 其他可点击元素(都能正常触发逻辑) -->
<button class="other-btn" id="logBtn">点击打印日志</button>
<button class="other-btn" id="insertBtn">点击插入文本到编辑区</button>
<div class="link" id="jumpLink">点击模拟跳转(不会真跳)</div>
<div class="popup-box" id="showPopupBtn">点击显示弹窗</div>
<div id="popup">这是弹窗内容(点击其他地方不会关闭,除非加逻辑)</div>
</div>
<script>
// 1. 获取核心元素
const editArea = document.getElementById('editArea');
const popup = document.getElementById('popup');
let lastRange = null; // 存储光标位置,用于恢复
// 2. 初始化:自动聚焦+光标定位到末尾
document.addEventListener('DOMContentLoaded', () => {
editArea.focus();
moveCursorToEnd(editArea);
});
// 3. 关键监听可编辑区域的blur事件即将失焦时
editArea.addEventListener('blur', () => {
// 延迟10ms重新聚焦让其他元素的点击逻辑先执行避免冲突
setTimeout(() => {
if (lastRange) { // 恢复之前的光标位置
editArea.focus();
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(lastRange);
}
}, 10);
});
// 4. 实时保存光标位置(确保失焦后能恢复)
editArea.addEventListener('selectionchange', () => {
const selection = window.getSelection();
if (selection.rangeCount > 0) {
// 克隆光标范围(避免原对象被覆盖)
lastRange = selection.getRangeAt(0).cloneRange();
}
});
// ---------------------- 以下是其他元素的正常点击逻辑(可自定义) ----------------------
// 按钮1打印日志正常触发
document.getElementById('logBtn').addEventListener('click', () => {
console.log('按钮被点击了!当前编辑区内容:', editArea.innerText);
alert('按钮点击成功!光标还在编辑区哦~');
});
// 按钮2插入文本到编辑区正常触发+光标同步)
document.getElementById('insertBtn').addEventListener('click', () => {
const insertText = '【插入的文本】';
const selection = window.getSelection();
const range = selection.getRangeAt(0);
// 插入文本(不影响原光标位置)
range.deleteContents();
const textNode = document.createTextNode(insertText);
range.insertNode(textNode);
// 光标移到插入文本末尾
range.setStartAfter(textNode);
range.setEndAfter(textNode);
selection.removeAllRanges();
selection.addRange(range);
// 确保编辑区仍有焦点(双重保险)
editArea.focus();
});
// 链接:模拟跳转(正常触发,不真跳转)
document.getElementById('jumpLink').addEventListener('click', () => {
alert('模拟跳转逻辑触发!(实际不会跳转,光标还在编辑区)');
});
// 区域:显示弹窗(正常触发)
document.getElementById('showPopupBtn').addEventListener('click', () => {
popup.style.display = popup.style.display === 'block' ? 'none' : 'block';
});
// ---------------------- 辅助函数 ----------------------
// 光标定位到编辑区末尾
function moveCursorToEnd(element) {
const range = document.createRange();
const selection = window.getSelection();
range.selectNodeContents(element);
range.collapse(false); // false=末尾true=开头
selection.removeAllRanges();
selection.addRange(range);
}
</script>
</body>
</html>