在安卓的webView中自帶的有搜索關(guān)鍵字、顯示關(guān)鍵字以及滾動,而iOS中webView并沒有這些功能,需要開發(fā)者自己實現(xiàn)。好了,閑話少說,進入正題。
我們可以通過WKWebView調(diào)用JS的方法來實現(xiàn)以上功能,JS代碼:
var MyApp_SearchResultCount = 0;
var MyApp_SearchResults = [];
var MyApp_selectSpan;
var MyApp_SwitchIndex = 0;
//根據(jù)關(guān)鍵字查找
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
? ? ? ? ? ? ? ? MyApp_SearchResults.push(span);
? ? ? ? ? ? }
? ? ? ? } 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);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
// 根據(jù)關(guān)鍵字查找 供WKWebView調(diào)用
function MyApp_HighlightAllOccurencesOfString(keyword) {
? ? MyApp_RemoveAllHighlights();
? ? MyApp_HighlightAllOccurencesOfStringForElement(document.body, keyword.toLowerCase());
}
// 關(guān)鍵關(guān)鍵字 移除高亮顯示
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;
}
//WKWebView調(diào)用移除高亮
function MyApp_RemoveAllHighlights() {
? ? MyApp_SearchResultCount = 0;
? ? MyApp_SearchResults = [];
? ? MyApp_RemoveAllHighlightsForElement(document.body);
}
//滾動到搜索到的第一個關(guān)鍵字
function MyApp_ScrollToFiristResult() {
? ? MyApp_ScrollToIndex(0);
}
//滾動到指定下標的關(guān)鍵字
function MyApp_ScrollToIndex(index) {
? ? if (MyApp_selectSpan) {
? ? ? ? MyApp_selectSpan.style.backgroundColor = "yellow";
? ? }
? ? var span = MyApp_SearchResults[MyApp_SearchResultCount - index - 1];
? ? span.style.backgroundColor = "orange";
? ? MyApp_selectSpan = span;
? ? var h = document.body.clientHeight; //獲取設(shè)備的高度
? ? window.scrollTo(0,span.offsetTop-h/2); //滾動到屏幕中央
}
// 上移
function MyApp_SwitchToUp() {
? ? MyApp_SwitchIndex--;
? ? if (MyApp_SwitchIndex < 0) {
? ? ? ? MyApp_SwitchIndex = MyApp_SearchResultCount-1;
? ? }
? ? MyApp_ScrollToIndex(MyApp_SwitchIndex);
? ? return MyApp_SwitchIndex;
}
// 下移
function MyApp_SwitchToDown() {
? ? MyApp_SwitchIndex++;
? ? if (MyApp_SwitchIndex >= MyApp_SearchResultCount) {
? ? ? ? MyApp_SwitchIndex = 0;
? ? }
? ? MyApp_ScrollToIndex(MyApp_SwitchIndex);
? ? return MyApp_SwitchIndex;
}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
為方便調(diào)用JS方法,可以將JS方法的調(diào)用寫到WKWebView的分類中,這樣WKWebView就有了這幾個功能,WKWebView+SearchWebView.h:
typedef void(^SearchResultBlock)(NSInteger searchCount);
// 搜索關(guān)鍵字 以及搜索完成之后的回調(diào) 查找的總數(shù)
- (void)highlightAllOccurencesOfString:(NSString*)str searchResultBlock:(SearchResultBlock)searchResultBlock;
//滾動到指定的下標
- (void)scrollToIndex:(NSInteger)index;
//上移
- (void)scrollToUp;
//下移
- (void)scrollDown;
//移除高亮
- (void)removeAllHighlights;
WKWebView+SearchWebView.m的實現(xiàn):
- (void)highlightAllOccurencesOfString:(NSString*)str searchResultBlock:(SearchResultBlock)searchResultBlock {
? ? NSString *path = [[NSBundle mainBundle] pathForResource:@"searchWebView" ofType:@"js"];
? ? NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
?//NSLog(@"jsCode==%@",jsCode);
? ? [self evaluateJavaScript:jsCode completionHandler:nil];
? ? NSString *startSearch = [NSString stringWithFormat:@"MyApp_HighlightAllOccurencesOfString('%@')",str];
? ? MJWeakSelf
? ? [self evaluateJavaScript:startSearch completionHandler:^(id _Nullable result, NSError * _Nullable error) {
? ? ? ? [weakSelf evaluateJavaScript:@"MyApp_ScrollToFiristResult()" completionHandler:nil];
? ? }];
?[self evaluateJavaScript:@"MyApp_SearchResultCount"
? ? ? ? ? completionHandler:^(id _Nullable result, NSError * _Nullable error) {
? ? ? ? ? ? ? searchResultBlock([result integerValue]);
? ? ? ? ? }];
}
- (void)scrollToIndex:(NSInteger)index {
? ? [self evaluateJavaScript:[NSString stringWithFormat:@"MyApp_ScrollToIndex(%ld)",index] completionHandler:^(id _Nullable result, NSError * _Nullable error) {
? ? }];
}
- (void)scrollToUp {
? ? [self evaluateJavaScript:@"MyApp_SwitchToUp()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
? }];
}
- (void)scrollDown {
? ? [self evaluateJavaScript:@"MyApp_SwitchToDown()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
?}];
}
- (void)removeAllHighlights {
? ? [self evaluateJavaScript:@"MyApp_RemoveAllHighlights()" completionHandler:nil];
}
好了,功能實現(xiàn)大致就是這些,歡迎吐槽~_~