- 修复键盘弹出时底部操作栏遮挡问题,添加固定定位效果 - 改进光标定位逻辑,适配不同输入场景 - 增加内容预填充功能,便于测试和演示 - 调整底部间距和动画高度,适配不同设备 - 添加vConsole调试工具便于移动端调试
160 lines
5.2 KiB
HTML
160 lines
5.2 KiB
HTML
<!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>
|