搜索WKWebView[UIWebView]中内容

柯唯
2023-12-01

今天接触很多未知的东西,一口气写了好几篇小博文了。
PS:这边文章我是参考了:iCab Blog 来写的,代码是swift版本的。
这篇文章主要介绍的是,在自己app中创建一个搜索框,搜索webview中的内容,搜索匹配的文字内容背景变色,字体改为黑色【其实样式都可以自己调整】

话不多说,直接上代码
JS代码:

// We're using a global variable to store the number of occurrences
var MyApp_SearchResultCount = 0;

// helper function, recursively searches in elements and their child nodes
function MyApp_HighlightAllOccurencesOfStringForElement(element,keyword) {
  if (element) {
    if (element.nodeType == 3) {        // Text node
      while (true) {
        var value = element.nodeValue;  // Search for keyword in text node
        var idx = value.toLowerCase().indexOf(keyword);

        if (idx < 0) break;             // not found, abort

        var span = document.createElement("span");
        var text = document.createTextNode(value.substr(idx,keyword.length));
        span.appendChild(text);
        span.setAttribute("class","MyAppHighlight");
        span.style.backgroundColor="yellow";
        span.style.color="black";
        text = document.createTextNode(value.substr(idx+keyword.length));
        element.deleteData(idx, value.length - idx);
        var next = element.nextSibling;
        element.parentNode.insertBefore(span, next);
        element.parentNode.insertBefore(text, next);
        element = text;
        MyApp_SearchResultCount++;  // update the counter
      }
    } else if (element.nodeType == 1) { // Element node
      if (element.style.display != "none" && element.nodeName.toLowerCase() != 'select') {
        for (var i=element.childNodes.length-1; i>=0; i--) {
          MyApp_HighlightAllOccurencesOfStringForElement(element.childNodes[i],keyword);
        }
      }
    }
  }
}

// the main entry point to start the search
function MyApp_HighlightAllOccurencesOfString(keyword) {
  MyApp_RemoveAllHighlights();
  MyApp_HighlightAllOccurencesOfStringForElement(document.body, keyword.toLowerCase());
}

// helper function, recursively removes the highlights in elements and their childs
function MyApp_RemoveAllHighlightsForElement(element) {
  if (element) {
    if (element.nodeType == 1) {
      if (element.getAttribute("class") == "MyAppHighlight") {
        var text = element.removeChild(element.firstChild);
        element.parentNode.insertBefore(text,element);
        element.parentNode.removeChild(element);
        return true;
      } else {
        var normalize = false;
        for (var i=element.childNodes.length-1; i>=0; i--) {
          if (MyApp_RemoveAllHighlightsForElement(element.childNodes[i])) {
            normalize = true;
          }
        }
        if (normalize) {
          element.normalize();
        }
      }
    }
  }
  return false;
}

// the main entry point to remove the highlights
function MyApp_RemoveAllHighlights() {
  MyApp_SearchResultCount = 0;
  MyApp_RemoveAllHighlightsForElement(document.body);
}

创建一个.js文件,将上面的代码复制粘贴上去,比较容易理解,就是2个方法实现,一个是遍历网页中的节点并且用递归遍历查找我们发送的keyword,并对其加属性【颜色之类的】;另一个方法则是撤销以加的属性,让网页恢复正常。

func highlightAllOccurencesOfString(str: String) {
        if let currentBrowser = self.currentBrowser {
            let path = NSBundle.mainBundle().pathForResource("SearchWebView", ofType: "js")!
            let jsCode = try! String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
            currentBrowser.webView.evaluateJavaScript(jsCode, completionHandler: nil)

            let startSearch = "MyApp_HighlightAllOccurencesOfString('\(str)')"
            currentBrowser.webView.evaluateJavaScript(startSearch, completionHandler: nil)
        }
    }

    func removeAllHighlights() {
        if let currentBrowser = self.currentBrowser {
            currentBrowser.webView.evaluateJavaScript("MyApp_RemoveAllHighlights()", completionHandler: nil)
        }
    }

这里是给自己的app添加和js之间的交互,这里我对原作者的代码做了一些修改,我的项目中不需要显示找出多少个匹配对象,所以在highlightAllOccurencesOfString(str: String)这个方法中我并没有做返回值的处理和设定。JS的代码本身是有返回查询数量的,有需要的朋友们,只在我们项目中进行调用获取就可以了。写到这里基本工作就已经完成了,解释一下highlightAllOccurencesOfString(str: String)这个方法吧。代码是我从项目中直接拉过来的所以一些定义处理或者是命名有可能误导大家。

let path = NSBundle.mainBundle().pathForResource("SearchWebView", ofType: "js")!
            let jsCode = try! String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
            currentBrowser.webView.evaluateJavaScript(jsCode, completionHandler: nil)

            let startSearch = "MyApp_HighlightAllOccurencesOfString('\(str)')"
            currentBrowser.webView.evaluateJavaScript(startSearch, completionHandler: nil)

这几行代码是核心,其他的处理可以根据自己的情况来进行修改,这里就不做多说了,相信大神们能看得懂。
这些方法都定义完成了,接下来我们就可以开始使用了!在想要触发的地方调用highlightAllOccurencesOfString(str)在结束搜索的地方调用removeAllHighlights()就可以了。以后要做项目的时候,直接将这几个方法和JS文件带走就好了。没有什么修改的地方,如果自己没事可以自定义一个searchBar这样一来,代码都不用修改直接带文件走。哈哈,是不是很爽?!就喜欢这样的感觉。好了,就到这里吧,希望对大家有帮助。再一次感谢iCab Blog 对我的帮助,比较赞的一个博客。

 类似资料: