Editor 過濾內容 - daniel-qa/Vue GitHub Wiki
過濾主要分三層:
貼上事件 pasteEvent
↓
normalizeSpacing(主要清洗)
↓
normalizeSafariSpaceSpans(空白修正)
↓
regex replace(Word / Office 污染清理)
👉 核心目標就三個:
1 .移除 Word / Office 垃圾 HTML
2 .修正空白(特別是 Safari + Word)
3 .保留乾淨結構 + 圖片
- Apple-converted-space: (針對 apple 的處理)
通常發生在從 Safari 瀏覽器、備忘錄 (Notes) 或 Pages 拷貝帶有格式的文字,再貼到網頁編輯器時。系統為了確保「你在 Apple 軟體上看到的間距」在 HTML 網頁上也能一模一樣,會自動把多餘的空格封裝成這個 class。
- dom 寫法(現代)
function sanitizeHTML(html) {
const doc = new DOMParser().parseFromString(html, 'text/html')
// 1. 移除垃圾 tag
doc.querySelectorAll('style, o\\:p, v\\:shape, v\\:imagedata')
.forEach(el => el.remove())
// 2. 清理 Safari 空白
doc.querySelectorAll('span').forEach(el => {
if (
el.classList.contains('Apple-converted-space') ||
/^\s+$/.test(el.textContent)
) {
el.replaceWith(document.createTextNode(el.textContent))
}
})
return doc.body.innerHTML
}
① 解析 HTML → 變成 DOM
const parser = new DOMParser()
const doc = parser.parseFromString(html, 'text/html')
💡 重點
👉 把這種字串:
👉 變成真正 DOM:
HTML → DOM Tree 🧠 為什麼這一步很重要?
因為你後面可以:
用 querySelectorAll 用 classList 不用 regex 猜結構
👉 這就是「現代寫法的核心優勢」
② 找出所有 span
doc.querySelectorAll('span')
👉 把所有 <span> 抓出來
🧠 為什麼不是直接抓 .Apple-converted-space?
因為你這段還多做了一件事:
/^\s+$/.test(el.textContent)
👉 👉 👉 這才是關鍵!
③ 判斷是不是「假空白」
const isAppleSpace =
el.classList.contains('Apple-converted-space') ||
/^\s+$/.test(el.textContent)
- regex 寫法(舊)
/* 粘贴文本的解析和轻量化操作 */
normalizeSafariSpaceSpans(htmlString) {
return htmlString.replace(/<span(?: class="Apple-converted-space"|)>(\s+)<\/span>/g, (fullMatch, spaces) => {
return spaces.length === 1 ? ' ' : Array(spaces.length + 1).join('\u00A0 ').substr(0, spaces
.length);
});
},