作为 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/