首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 正則替換:在指定字元後插入 HTML 標籤 (按鈕)

     編輯:程式設計綜合問答

需求

頁面內容含特殊標記 `#`,需在每個 `#` 後插入一個按鈕:


// 原始內容
xxxxx
#target#
yyyyy

// 期望結果
xxxxx
#target#
yyyyy

核心思路:字串替換而非 DOM 操作

直接操作 `innerHTML` 會破壞事件綁定、選區、輸入框狀態。最佳實踐:取得文字 → 正則替換 → 寫回 innerHTML → 事件委託。

實現代碼


function injectButtonsAfterHash(containerSelector, buttonHtml) {
    const container = document.querySelector(containerSelector);
    if (!container) return;
    
    // 1. 獲取純文字內容 (避免破壞現有標籤)
    // 若容器含複雜結構,建議用 TreeWalker 遍歷文字節點
    let text = container.textContent || container.innerText;
    
    // 2. 正則替換:匹配 # 後插入按鈕 HTML
    // 使用佔位符避免重複替換已插入的按鈕內的 #
    const placeholder = '___HASH_PLACEHOLDER___';
    text = text.replace(/#/g, placeholder);          // 先保護所有 #
    text = text.replace(new RegExp(placeholder, 'g'), `#${buttonHtml}`);
    
    // 3. 寫回 (僅演示,實際建議針對文字節點替換)
    container.innerHTML = text; // 注意:會移除容器內原有標籤與事件
    
    // 4. 事件委託 (容器層級綁定一次)
    container.addEventListener('click', e => {
        if (e.target.matches('.injected-btn')) {
            const hashText = e.target.previousSibling?.textContent?.trim() || '';
            console.log('按鈕點擊,關聯標記:', hashText);
            // 業務邏輯...
        }
    });
}

// 使用
const btnHtml = '';
injectButtonsAfterHash('#content-area', btnHtml);

進階:精準處理文字節點 (不破壞現有 DOM)


function injectInTextNodes(root, targetChar, injectHtml) {
    const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
    const textNodes = [];
    while (walker.nextNode()) textNodes.push(walker.currentNode);
    
    textNodes.forEach(node => {
        if (node.textContent.includes(targetChar)) {
            const span = document.createElement('span');
            // 將文字按 targetChar 分割,交替插入文字節點與按鈕
            const parts = node.textContent.split(new RegExp(`(${targetChar})`));
            parts.forEach((part, i) => {
                if (part === targetChar) {
                    span.appendChild(document.createTextNode(part));
                    const btn = document.createElement('span');
                    btn.innerHTML = injectHtml;
                    btn.className = 'injected-btn-wrapper';
                    span.appendChild(btn);
                } else if (part) {
                    span.appendChild(document.createTextNode(part));
                }
            });
            node.parentNode.replaceChild(span, node);
        }
    });
}

// 使用
injectInTextNodes(document.getElementById('content'), '#', '');

關鍵點總結

方法優點缺點適用場景
innerHTML 替換代碼簡單破壞現有事件/輸入狀態、XSS 風險純靜態內容、初始化渲染
TreeWalker 文字節點替換保留原有 DOM/事件、安全代碼較複雜富文本編輯器、動態頁面
虛擬 DOM (React/Vue)框架層面解決需框架支持現代前端專案

安全提醒

若標記內容來自用戶輸入,務必對 `buttonHtml` 及周圍文字進行 HTML 編碼,防止 XSS:


function escapeHtml(str) {
    return str.replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved