javascript - 如何使用 Swift 将鼠标悬停在 URL 上进入 WkWebView

标签 javascript swift macos cocoa wkwebview

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

我需要在鼠标悬停时获取 URL,这是上下文菜单出现的前奏,因此我可以将其注入(inject)菜单项的 respresentedObject - 或者以其他方式保存。某些项目的内置操作未得到正确处理。

我发现“打开链接”的菜单项操作正常,但“在新窗口中打开链接”却不行;这些都不是通过内置的上下文菜单项操作来工作的。我想支持单击中间按钮成为后一个菜单项。

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

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

然后在 View Controller 中

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,而不是鼠标悬停时突出显示的内容。

我需要的是获取 URL 等,如鼠标悬停在 Web 浏览器的状态栏中所示,以便缓存上下文菜单项的操作。

最佳答案

嗯,我想,在您的 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 世界中,您需要捕获“newUrlDetected”

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

在 Swift 消息处理程序中,您需要打开 WKScriptMessage 名称属性。

  • 如果是“newSelectionDetected”,则设置webView.selectedText为消息正文
  • 如果是“newUrlDetected”,则设置webView.selectedURL为消息正文

关于javascript - 如何使用 Swift 将鼠标悬停在 URL 上进入 WkWebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51894733/

相关文章:

javascript - 为什么不允许JS forEach函数中的 'break'?

ios - 定义结构时的错误信息

swift - 数据迁移后的 Codesign keychain 问题 : "The specified item could not be found in the keychain."

javascript - 移动导航 "Back"链接问题

javascript - 限制文本字段中的整数

javascript - 使用命令行选项时如何在 CasperJS 中保留长数字?

ios - 使用 mediaType Video 从 PHAsset 修改元数据失败

swift - 如何获得最多 2 个小数位的 Double 值

c - macOS 上的 Pacman fork

macos - SceneKit 平滑相机移动