You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WKWebView网页中查找并高亮标签间文本,实现浏览器查找功能

iOS WKWebView 文本搜索高亮实现方案

原代码失效根因

  • iOS端WKWebView内核限制了document.execCommand编辑类接口的使用,BackColor、HiliteColor等命令均无法生效
  • window.find在移动端WebKit中存在行为兼容问题,无法稳定匹配跨HTML标签的连续文本
  • document.designMode切换在WKWebView中会触发未知渲染异常,无法实现预期效果

兼容实现方案

放弃依赖浏览器原生编辑命令,改用DOM节点遍历、手动包裹高亮标签的方案,该方案完全兼容WKWebView,同时天然支持跨标签文本匹配,完整可运行代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>WKWebView 文本高亮测试页</title>
    <style>
        /* 可自定义高亮样式 */
        .search-highlight {
            background-color: #ff0;
            font-weight: inherit;
        }
    </style>
</head>
<body>
    <input type="text" id="search" autofocus onkeyup="highlight(this.value);" />
       
    <div id="content">
        <p>Here is some searchable <b>text</b> with some lápices in it, and more lápices, and some <b>for<i>mat</i>t</b>ing</p>
    </div>
        
    <script type="text/javascript">
        // 移除所有已有高亮,还原原生DOM结构
        function unhighlight() {
            const highlights = document.querySelectorAll('.search-highlight');
            highlights.forEach(highlight => {
                const parent = highlight.parentNode;
                parent.replaceChild(document.createTextNode(highlight.textContent), highlight);
                parent.normalize();
            });
        }

        // 递归获取节点下所有文本节点
        function getTextNodes(node) {
            const textNodes = [];
            if (node.nodeType === Node.TEXT_NODE) {
                textNodes.push(node);
            } else {
                for (let i = 0; i < node.childNodes.length; i++) {
                    textNodes.push(...getTextNodes(node.childNodes[i]));
                }
            }
            return textNodes;
        }

        // 高亮匹配的搜索词
        function highlight(searchText, caseSensitive = false) {
            unhighlight();
            const trimText = searchText.trim();
            if (!trimText) return;

            const flags = caseSensitive ? 'g' : 'gi';
            // 转义正则特殊字符
            const escapedText = trimText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
            const regex = new RegExp(escapedText, flags);
            const textNodes = getTextNodes(document.body);

            textNodes.forEach(node => {
                if (!regex.test(node.textContent)) return;
                let lastIndex = 0;
                const fragment = document.createDocumentFragment();
                
                node.textContent.replace(regex, (match, index) => {
                    if (index > lastIndex) {
                        fragment.appendChild(document.createTextNode(node.textContent.slice(lastIndex, index)));
                    }
                    const highlightSpan = document.createElement('span');
                    highlightSpan.className = 'search-highlight';
                    highlightSpan.textContent = match;
                    fragment.appendChild(highlightSpan);
                    lastIndex = index + match.length;
                });

                if (lastIndex < node.textContent.length) {
                    fragment.appendChild(document.createTextNode(node.textContent.slice(lastIndex)));
                }
                node.parentNode.replaceChild(fragment, node);
            });
        }
    </script>
</body>
</html>

方案优势

  • 不依赖任何浏览器私有接口,全版本iOS WKWebView均可正常运行
  • 不会修改原页面的DOM结构逻辑,清除高亮后完全还原初始页面状态
  • 支持特殊字符、中文、带重音符号的字符匹配,可通过参数自定义是否大小写敏感

内容的提问来源于stack exchange,提问作者Prince

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 05:12:03