WebView: angezeigter Text eines Links herausfinden

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • WebView: angezeigter Text eines Links herausfinden

    Hallo zusammen

    Ich habe eine WebView in einem ViewController. In diesem lade ich eine html-Datei, welche verschiedene Links enthält. Ich möchte nun, wenn ich auf einen Link in der WebView klicke, dass ich den angezeigten Text des Links erhalte. Auch wenn der Link über mehrere Wörter sich erstreckt, sollten alle Wörter des Links angezeigt werden.

    Die url des Links habe ich bereits mit folgendem Code herausgefunden:

    Quellcode

    1. func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    2. if let url = webView.url?.absoluteString{
    3. print("url = \(url)")
    4. }


    Hat jemand eine Idee?
  • Runner89 schrieb:

    Ich möchte nun, wenn ich auf einen Link in der WebView klicke, dass ich den angezeigten Text des Links erhalte. Auch wenn der Link über mehrere Wörter sich erstreckt, sollten alle Wörter des Links angezeigt werden.
    Vielleicht liegt es nur an mir oder an der späten Stunde, aber ich verstehe Dein Problem nicht: Was ist der Text eines Links? Meinst Du, der entsprechende HTTP-Request wird nicht ausgeführt und entsprechend kannst Du Links nicht auf weitere HTML-Seiten folgen? Und wie erstreckt sich ein Link über mehrere Wörter? Ich vermute einen längeren Text den Anchor-Tag, aber für mich bleibt Deine Problembeschreibung rätselhaft.

    Vielleicht kannst Du Deine Frage etwas "technischer" stellen? Welches Verhalten erwartest Du, welchen Effekt hast Du und wie sieht das entsprechende HTML aus?

    Sorry, falls es nur an mir liegt, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Ich versuche es mal anders zu formulieren:

    In der html-Datei steht folgender Code, welcher in der WebView geladen wird.

    HTML-Quellcode

    1. <p><a href="https://www.bing.com/search?q=Auto">Bing Suche Auto</a></p>
    Wenn ich auf den Text "Bing Suche Auto" klicke, wird die entsprechende Internetseite geladen.

    Ich möchte nun, dass durch Drücken auf den Text "Bing Suche Auto" bzw. durch Drücken auf den Link, der "angezeigte Text", also "Bing Suche Auto", herausgegeben wird, da ich diesen später als String benötige und danach die entsprechende Internetseite lädt.

    Ich hoffe, es ist so verständlicher.
  • Ich habe dir mal ein Beispiel in SwiftUI gemacht, welches ich so einfach wie möglich gehalten habe. Es besteht aus der WebView-Komponente, die gleich ein UserScript in die Seite injiziert. Das UserScript greift sich alle Links und sendet beim Klicken auf einen Link den Text und die URL über den ScriptMessageHandler zurück zur App, wo es dann verarbeitet und angezeigt wird.

    Hier die WebView.swift

    Quellcode: WebView.swift

    1. import Foundation
    2. import SwiftUI
    3. import WebKit
    4. enum ScriptMessage {
    5. case link(String, String)
    6. case alert(String)
    7. }
    8. struct WebView: UIViewRepresentable {
    9. let webView: WKWebView = WKWebView()
    10. let url: URL
    11. var onScriptMessage: ((_ message: ScriptMessage) -> Void)?
    12. func open(url: URL) {
    13. webView.load(URLRequest(url: url))
    14. }
    15. func makeCoordinator() -> Coordinator {
    16. return Coordinator(self)
    17. }
    18. func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
    19. let script = WKUserScript(source: "document.querySelectorAll('a').forEach((a) => { a.onclick = (e) => { webkit.messageHandlers.app.postMessage({ name: 'link', text: a.textContent, url: a.href }) } })", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
    20. webView.configuration.userContentController.addUserScript(script)
    21. webView.configuration.userContentController.add(context.coordinator, name: "app")
    22. webView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true
    23. webView.isExclusiveTouch = true
    24. webView.navigationDelegate = context.coordinator
    25. webView.uiDelegate = context.coordinator
    26. return webView
    27. }
    28. func updateUIView(_ webView: WKWebView, context: Context) {
    29. open(url: url)
    30. }
    31. class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate {
    32. private var owner: WebView
    33. init(_ owner: WebView) {
    34. self.owner = owner
    35. }
    36. func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    37. if (message.name == "app") {
    38. if let body = message.body as? [String:Any], let name = body["name"] as? String {
    39. switch name {
    40. case "link":
    41. if let linkText = body["text"] as? String, let linkUrl = body["url"] as? String {
    42. owner.onScriptMessage?(.link(linkText, linkUrl))
    43. }
    44. case "alert":
    45. if let value = body["value"] as? String {
    46. owner.onScriptMessage?(.alert(value))
    47. }
    48. default:
    49. print("Message \(name) not handled")
    50. }
    51. }
    52. }
    53. }
    54. }
    55. }
    Alles anzeigen



    Und hier die ContentView.swift:

    Quellcode: ContentView.swift

    1. import SwiftUI
    2. struct ContentView: View {
    3. @State var url = URL(string: "https://calculy.app")!
    4. @State var linkText: String?
    5. @State var linkUrl: String?
    6. var body: some View {
    7. VStack {
    8. HStack {
    9. Text(linkText ?? "Kein Linktext")
    10. Spacer()
    11. Text(linkUrl ?? "Keine URL")
    12. }
    13. .padding()
    14. WebView(url: url) { message in
    15. switch message {
    16. case .link(let text, let url):
    17. linkText = text
    18. linkUrl = url
    19. case .alert(let value):
    20. print(value)
    21. }
    22. }
    23. }
    24. }
    25. }
    Alles anzeigen

    Das UserScript ist zwar schon in der WebView.swift drin, da es als Einzeiler aber schwer zu lesen ist, hier noch mal das formatierte JavaScript, welches die Links sendet:

    JavaScript-Quellcode: WKUserScript

    1. document.querySelectorAll('a').forEach((a) => {
    2. a.onclick = (e) => {
    3. webkit.messageHandlers.app.postMessage({
    4. name: 'link',
    5. text: a.textContent,
    6. url: a.href
    7. })
    8. }
    9. })
    So Long, and Thanks for All the Fish.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Babelfisch () aus folgendem Grund: Kleine Änderung am Javascript.

  • Runner89 schrieb:

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
    An der Stelle ist es auf jeden Fall schon zu spät… aber ich würde mir gut überlegen, ob der Titel der neuen Website nicht besser für deine Zwecke geeignet ist — der ist mitunter aussagekräftiger, und einfacher rauszufinden.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von t-no ()