首页 文章

如何使用Swift将鼠标悬停在WkWebView上

提问于
浏览
0

作为How do I get the selected text from a WKWebView from objective-C的后续,我有一个相关的问题,但使用Swift .

我需要获取鼠标悬停的URL,在上下文菜单外观的前奏,所以我可以将它注入菜单项的respresentedObject - 或以其他方式保存 . 某些项目的内置操作未得到妥善处理 .

我发现“Open Link”的菜单项操作工作正常但不适用于“新窗口中的Open Link”;这些都不是通过内置的上下文菜单项操作来完成的 . 我想支持中间按钮单击以作为后一个菜单项 .

因此,使用原始帖子作为基础我有这个 - 我也是子类WkWebView,添加

class MyWebView : WKWebView {
    var selectedText : String?
    var selectedURL : URL?
}

然后在视图控制器中

func viewDidLoad() {
    //  Watch javascript selection messages
    let controller = webView.configuration.userContentController
    controller.add(self, name: "newSelectionDetected")
    let js = """
function getSelectionAndSendMessage()
{
    var txt = document.getSelection().toString() ;
    window.webkit.messageHandlers.newSelectionDetected.postMessage(txt) ;
}
document.onmouseup   = getSelectionAndSendMessage ;
document.onkeyup     = getSelectionAndSendMessage ;
"""

    let script = WKUserScript.init(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
    controller.addUserScript(script)
}

// MARK: Javascript

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    Swift.print("userContentController")

    // A new selected text has been received
    if let urlString : String = message.body as? String
    {
        webView.selectedText = urlString
        Swift.print("ucc: str -> \(urlString)")
    }
    if let url = message.frameInfo.request.url {
        webView.selectedURL = url
        Swift.print("ucc: url -> \(url.absoluteString)")
    }
}

// MARK: callbacks
override func willOpenMenu(_ menu: NSMenu, with event: NSEvent) {

    //  Pick off javascript items we want to ignore or handle
    for title in ["Open Link", "Open Link in New Window", "Download Linked File"] {
        if let item = menu.item(withTitle: title) {
            if title == "Download Linked File" {
                menu.removeItem(item)
            }
            else
            if title == "Open Link"
            {
                item.representedObject = self.window
                item.action = #selector(MyWebView.openLinkInWindow(_:))
                item.target = self
            }
            else
            {
                item.action = #selector(MyWebView.openLinkNewWindow(_:))
                item.target = self
            }
        }
    }
}

在我的动作处理程序中,我只获取框架的URL,而不是鼠标悬停的内容 .

我需要的是在鼠标悬停的Web浏览器状态栏中显示URL等,以便为上下文菜单项的操作进行缓存 .

1 回答

  • 1

    好吧,我想在你的javascript中,你需要为你的所有链接添加一个onmouseover事件处理程序,这个事件处理程序应该将链接发送回swift世界 .

    在你的代码的基础上,我会在Javascript中添加如下内容:

    function sendLink()
    {
        window.webkit.messageHandlers.newUrlDetected.postMessage(this.href) ;
    }
    
    var allLinks = document.links;
    for(var i=0; i< allLinks.length; i++)
    {
        allLinks[i].onmouseover = sendLink ;
    }
    

    当然,在Swift世界中,你需要 grab “newUrlDetected”

    controller.add(self, name: "newUrlDetected")
    

    在Swift消息处理程序中,您需要切换WKScriptMessage名称属性 .

    • 如果是"newSelectionDetected",则使用消息正文设置webView.selectedText

    • 如果是"newUrlDetected",则使用消息正文设置webView.selectedURL

相关问题