[英]how to get mouse over URLs into WkWebView with 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. 作为我如何从Objective-C的WKWebView获取所选文本的后续 ,我有一个相关的问题,但使用Swift。
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. 在上下文菜单出现的前奏中,我需要在鼠标悬停时获取URL,以便可以将其注入菜单项的respresentedObject-或进行保存。 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.
我希望支持单击中键成为后一个菜单项。
So, using the original post as a base I have this - I also sub-class WkWebView, adding 所以,以原始帖子为基础,我有这个-我也将WkWebView子类化,添加
class MyWebView : WKWebView {
var selectedText : String?
var selectedURL : URL?
}
then in 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
}
}
}
}
In my action handler, I'm only getting the frame's URL, not what was highlighted on mouse over. 在我的动作处理程序中,我仅获取框架的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. 我需要的是获取鼠标悬停时Web浏览器状态栏中显示的URL等,以缓存上下文菜单项的操作。
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中,您需要向所有链接添加onmouseover事件处理程序,并且该事件处理程序应将链接发送回快速的世界。
Building upon your code, I would add in the Javascript something like: 在您的代码的基础上,我将在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 ;
}
And of course, in the Swift world, you need to catch the "newUrlDetected" 当然,在Swift世界中,您需要捕获“ newUrlDetected”
controller.add(self, name: "newUrlDetected")
And in the Swift message handler, you need to switch upon the WKScriptMessage name property. 在Swift消息处理程序中,您需要打开WKScriptMessage name属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.