如何使用Swift将鼠标悬停在URL上WkWebView [英] how to get mouse over URLs into WkWebView with Swift
问题描述
作为如何从Objective-C的WKWebView中获取所选文本,我有一个相关的问题,但使用的是Swift。
As a follow-up to How do I get the selected text from a WKWebView from objective-C, I have a related question but using Swift.
我需要获取将鼠标悬停在URL上,以显示上下文菜单外观,因此我可以将其注入菜单项的respresentedObject-或保存。某些项目的内置操作未正确处理。
I need to obtain the URL on mouse over, in prelude to contextual menu appearance, so I can inject it into the menu item's respresentedObject - or otherwise save. The built-in action(s) for some items are not being properly handled.
我发现打开链接的菜单项操作正常,但对于新窗口中的打开链接却不起作用;这些都不能通过内置的上下文菜单项操作来工作。我希望支持单击中间按钮成为后一个菜单项。
I find that menu item action for 'Open Link' works fine but not for 'Open Link in New Window'; neither of these work via the built-in contextual menu item actions. I wanted to support a middle button click to be the latter menu item.
因此,以原始帖子为基础,我有这个功能-我也将WkWebView子类化,添加
So, using the original post as a base I have this - I also sub-class WkWebView, adding
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
}
}
}
}
在我的动作处理程序中, m仅获取框架的URL,而不是鼠标悬停时突出显示的内容。
In my action handler, I'm only getting the frame's URL, not what was highlighted on mouse over.
我需要的是获取鼠标悬停时Web浏览器状态栏中显示的URL等,以缓存上下文菜单项的操作。
What I need, is to get the URL etc as shown in a web browser's status bar on mouse overs to be cached for a contextual menu item's action.
推荐答案
好吧,我想在您的JavaScript中,您需要向所有链接添加onmouseover事件处理程序,并且该事件处理程序应发送
Well, I guess that, in your javascript, you need to add a onmouseover event handler to all your links, and this event handler should send the link back to the swift world.
在您的代码的基础上,我将在Javascript中添加以下内容:
Building upon your code, I would add in the Javascript something like:
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
And of course, in the Swift world, you need to catch the "newUrlDetected"
controller.add(self, name: "newUrlDetected")
在Swift消息处理程序中,您需要打开WKScriptMessage名称属性。
And in the Swift message handler, you need to switch upon the WKScriptMessage name property.
- 如果它是 newSelectionDetected,则将webView.selectedText设置为邮件正文
- 如果它是 newUrlDetected,则将webView.selectedURL设置为邮件正文
这篇关于如何使用Swift将鼠标悬停在URL上WkWebView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!