如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
contenteditable 是实现轻量级所见即所得编辑框的最直接方案,无需富文本库,但需清洗 html 字符串防 xss,设置可访问性属性、禁用右键菜单,并用 innerhtml 取值后正则过滤危险标签与事件属性。

用 contenteditable 实现轻量级编辑框,不依赖富文本库
纯 HTML 表单里塞一个「所见即所得」编辑区,contenteditable 是最直接的解法。它不需要引入 quill、tiptap 或其他重型库,适合快速发布场景(比如后台简易文章草稿框)。但注意:它返回的是 HTML 字符串,不是纯文本,提交前得清洗或转义。
- 给
<div> 加 <code>contenteditable="true",再设role="textbox"和aria-label保证基础可访问性 - 禁用默认右键菜单(避免粘贴格式混乱):加
oncontextmenu="return false;" - 用
style="min-height: 200px; outline: none; padding: 12px; border: 1px solid #ddd; line-height: 1.5;"控制基础样式,避免空白时塌陷 - 别用
designMode或 iframe —— 过于重,且跨域/沙箱限制多 - 取值用
element.innerHTML.trim(),不是textContent(后者丢掉所有格式) - 简单过滤:用正则去掉危险标签(如
<script></script>、<iframe></iframe>)和onerror等事件属性,例如:html.replace(/<script>)<[^<]*)*<\/script>/gi, '')</script> - 若后端只接受 Markdown,前端可用
to-markdown库转换,但注意它不处理嵌套或复杂 HTML - 提交前检查是否为空:
!html.replace(/]*>/g, '').trim(),防止只留空标签 - 服务端返回的内容,先用 DOMPurify 清洗(如果允许 JS 运行),再赋给
element.innerHTML - 为统一换行行为,建议服务端始终用
<p></p>包裹段落,前端 CSS 加p { margin: 0.5em 0; } - 不要用
innerText回填 —— 它会把<br>当成空格,破坏结构 - 若发现粘贴进来的 Word 内容带大量
style属性,可在前端用html.replace(/ style="[^"]*"/gi, '')批量剥离 - 确保父容器有明确高度,且未设置
overflow: hidden—— 否则 iOS 键盘弹起时编辑区被裁切 - 监听
focus事件,用setTimeout(() => element.scrollIntoView({ behavior: 'smooth' }), 100)强制滚动到可视区 - Android 下回车默认插入
<div>,iOS 插入 <code><br>;如需统一段落行为,可拦截keydown中的Enter,阻止默认并手动插入<p><br></p> - 避免在编辑框上同时绑定
input和blur做实时保存 —— 移动端频繁触发会导致卡顿或重复提交
实际用起来,最易忽略的是服务端对 HTML 内容的二次校验 —— 前端清洗只是第一道防线,后端仍要解析、白名单过滤、转义输出。否则哪怕前端再严谨,绕过 JS 提交恶意 HTML 依然可行。
表单提交时正确获取和清理 contenteditable 内容
用户输入后,innerHTML 会包含各种标签(<div>、<code><br>、内联样式),直接 POST 可能引发 XSS 或后端解析失败。必须做最小化清洗。
回填编辑框内容时保留换行与段落结构
编辑已有文章再提交,需把服务端返回的 HTML 安全注入到 contenteditable 区域。直接赋值 innerHTML 有风险,且浏览器对换行渲染不一致(<br> vs <p></p>)。
移动端光标定位与键盘兼容性问题
在 iOS Safari 或 Android Chrome 上,contenteditable 常出现光标卡住、回车无反应、软键盘遮挡等问题,根源是浏览器对焦点和输入事件的处理差异。










