Luc*_*tti 5 objective-c uikit ios swift wkwebview
给定WKWebView显示网页,如何获取WKWebView由特定css选择器标识的HTML元素的位置(进入我的框架)?
这里突出显示的DIV的位置应该是 (0, 123)
如果滚动HTML内容,则应该是相同DIV的位置 (0, 0)
谢谢
这里的问题是 WKWebView 缩放其内容的大小。在 scrollView 中查找元素框架的技巧是找出 WKWebView 缩放内容的程度。您可以通过将滚动视图的内容大小与 javascript 返回的文档大小进行比较来找到此比例。下面是我能够在 XCode 8.3.2 中运行的 XCode 游乐场内容。
这将为您提供滚动视图中图像的位置。要获得 web 视图中的位置,只需减去
scrollview.contentOffset.y
特尔;博士:
webView.evaluateJavaScript("document.documentElement.clientHeight;") { (value, error) in
self.documentHeight = value as! CGFloat
let zoom = webView.scollView.zoomScale
}
Run Code Online (Sandbox Code Playgroud)
_
import Foundation
import WebKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let content = "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam mauris massa, ornare et ullamcorper a, tristique et odio. Nullam eleifend ex id ante placerat, sit amet feugiat arcu mollis. Sed iaculis lobortis lacus, in fermentum urna sodales at. Integer eget eleifend risus. Aenean feugiat turpis in odio sodales, id volutpat nisi pellentesque. Nunc eleifend nisl nunc, quis blandit nulla posuere ultricies. Nullam varius accumsan neque, vitae imperdiet ante consectetur vel. Fusce ullamcorper eu odio eleifend egestas. <img src=\"https://imgs.xkcd.com/comics/wisdom_of_the_ancients.png\" width=\"98%\"/> Proin elementum odio non massa pulvinar laoreet. Duis tincidunt augue vel placerat euismod. Mauris tincidunt felis at tellus convallis bibendum. Suspendisse purus dolor, lacinia eget tempor feugiat, vestibulum in risus. In non dui nec nisl porttitor pulvinar. Aliquam consectetur nisl at arcu consequat dapibus. Sed ex ante, condimentum vitae diam non, cursus dapibus ligula.<br /><img src=\"https://imgs.xkcd.com/comics/wisdom_of_the_ancients.png\" width=\"98%\"/></p>"
let jsImages = "var images = document.getElementsByTagName('img');" +
"var values = [];" +
"for (var i = 0; i < images.length; i++) {" +
"var rect = images[i].getBoundingClientRect();" +
"values = values.concat(rect.left, rect.top, rect.width, rect.height);" +
"};" +
"values;"
let jsHeight = "document.documentElement.clientHeight;"
class CustomWebView: WKWebView, WKNavigationDelegate {
var imageLocations: [CGRect] = []
var documentHeight: CGFloat?
func getImages() {
self.evaluateJavaScript(jsImages) { (values, error) in
print("=====\nValues from Javascript: \(values)")
if let values = values as? [Any] {
let numImages = values.count / 4 // jsImages returns four-value sets
for set in 0..<numImages {
let offset = set * 4
let imageFrame = self.jsToSwift(x: values[offset] as! CGFloat, y: values[offset+1] as! CGFloat, w: values[offset+2] as! CGFloat, h: values[offset+3] as! CGFloat)
self.imageLocations.append(imageFrame)
}
print("=====\nScrollview content size: \(self.scrollView.contentSize)")
print("=====\nFrames in WebView's ScrollView:\n\(self.imageLocations)\n=====")
}
}
}
func getHeight(callback: @escaping (() -> Void)) {
// Evaluate document height
self.evaluateJavaScript(jsHeight) { (value, error) in
self.documentHeight = value as? CGFloat
callback()
}
}
func jsToSwift(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) -> CGRect {
guard let documentHeight = documentHeight else {
return CGRect.zero
}
let zoom = scollView.zoomScale
let swiftX = x * zoom
let swiftY = y * zoom
let swiftW = w * zoom
let swiftH = h * zoom
return CGRect(x: swiftX, y: swiftY, width: swiftW, height: swiftH)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.getHeight { [weak self] (error) in
self?.getImages()
}
}
}
let webView = CustomWebView(frame: CGRect.zero, configuration: WKWebViewConfiguration())
webView.navigationDelegate = webView
webView.loadHTMLString(content, baseURL: nil)
Run Code Online (Sandbox Code Playgroud)
示例输出:
=====
Values from Javascript: Optional(<__NSArrayM 0x610000049510>(
8,
1528,
485,
270,
8,
2878,
485,
270
)
)
=====
Scrollview content size: (123.0, 791.0)
=====
Frames in WebView's ScrollView:
[(2.0, 382.0, 121.25, 67.5), (2.0, 719.5, 121.25, 67.5)]
=====
Run Code Online (Sandbox Code Playgroud)