在 WKWebView 中加载网站后,如何检测元素何时可见?
How can I detect when an element is visible after loading website in WKWebView?
我正在尝试加载一个公交网站,以便抓取给定停靠点的停靠时间。在我加载 url 之后,停止时间稍后会通过 javascript 动态加载。我的目标是检测 class 为 "stop-time" 的元素是否存在。如果这些元素出现在 html 中,我就可以解析 html。但是在我可以解析 html 之前,我必须等待 class of "stop-time" 这些元素出现。我通读了一堆其他的 SO 问题,但我无法将它们拼凑在一起。我正在实现 didReceive 消息函数,但我不确定如何加载 javascript 我需要检测元素的存在(class 或 "stop-time" 的元素)。我成功地注入了一些 javascript 以防止显示位置权限弹出窗口。
override func viewDidLoad() {
super.viewDidLoad()
let contentController = WKUserContentController()
let scriptSource = "navigator.geolocation.getCurrentPosition = function(success, error, options) {}; navigator.geolocation.watchPosition = function(success, error, options) {}; navigator.geolocation.clearWatch = function(id) {};"
let script = WKUserScript(source: scriptSource, injectionTime: .atDocumentStart, forMainFrameOnly: true)
contentController.addUserScript(script)
let config = WKWebViewConfiguration()
config.userContentController = contentController
webView = WKWebView(frame: .zero, configuration: config)
self.view = self.webView!
loadStopTimes("https://www.website.com/stop/1000")
}
func loadStopTimes(_ busUrl: String) {
let urlString = busUrl
let url = URL(string: urlString)!
let urlRequest = URLRequest(url: url)
webView?.load(urlRequest)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if(message.name == "stopTimesLoaded") {
// stop times now present so take the html and parse the stop times
}
}
首先,您需要注入下一个脚本以通过突变观察器检测元素的出现:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log('mutation.type = ' + mutation.type);
for (var i = 0; i < mutation.addedNodes.length; i++) {
var node = mutation.addedNodes[i];
if (node.nodeType == Node.ELEMENT_NODE && node.className == 'stop-time') {
var content = node.textContent;
console.log(' "' + content + '" added');
window.webkit.messageHandlers.stopTimesLoaded.postMessage({ data: content });
}
}
});
});
observer.observe(document, { childList: true, subtree: true });
那么您需要订阅活动 'stopTimesLoaded':
contentController.add(self, name: "stopTimesLoaded")
最后添加代码处理
中的数据
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
我正在尝试加载一个公交网站,以便抓取给定停靠点的停靠时间。在我加载 url 之后,停止时间稍后会通过 javascript 动态加载。我的目标是检测 class 为 "stop-time" 的元素是否存在。如果这些元素出现在 html 中,我就可以解析 html。但是在我可以解析 html 之前,我必须等待 class of "stop-time" 这些元素出现。我通读了一堆其他的 SO 问题,但我无法将它们拼凑在一起。我正在实现 didReceive 消息函数,但我不确定如何加载 javascript 我需要检测元素的存在(class 或 "stop-time" 的元素)。我成功地注入了一些 javascript 以防止显示位置权限弹出窗口。
override func viewDidLoad() {
super.viewDidLoad()
let contentController = WKUserContentController()
let scriptSource = "navigator.geolocation.getCurrentPosition = function(success, error, options) {}; navigator.geolocation.watchPosition = function(success, error, options) {}; navigator.geolocation.clearWatch = function(id) {};"
let script = WKUserScript(source: scriptSource, injectionTime: .atDocumentStart, forMainFrameOnly: true)
contentController.addUserScript(script)
let config = WKWebViewConfiguration()
config.userContentController = contentController
webView = WKWebView(frame: .zero, configuration: config)
self.view = self.webView!
loadStopTimes("https://www.website.com/stop/1000")
}
func loadStopTimes(_ busUrl: String) {
let urlString = busUrl
let url = URL(string: urlString)!
let urlRequest = URLRequest(url: url)
webView?.load(urlRequest)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if(message.name == "stopTimesLoaded") {
// stop times now present so take the html and parse the stop times
}
}
首先,您需要注入下一个脚本以通过突变观察器检测元素的出现:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log('mutation.type = ' + mutation.type);
for (var i = 0; i < mutation.addedNodes.length; i++) {
var node = mutation.addedNodes[i];
if (node.nodeType == Node.ELEMENT_NODE && node.className == 'stop-time') {
var content = node.textContent;
console.log(' "' + content + '" added');
window.webkit.messageHandlers.stopTimesLoaded.postMessage({ data: content });
}
}
});
});
observer.observe(document, { childList: true, subtree: true });
那么您需要订阅活动 'stopTimesLoaded':
contentController.add(self, name: "stopTimesLoaded")
最后添加代码处理
中的数据func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)