JavaFX WebView自定义右键菜单获取右键点击链接URL的方法及href为空问题排查
JavaFX WebView自定义右键菜单获取右键点击链接URL的方法及href为空问题排查
我来帮你搞定这个问题!你现在遇到的核心困境是:自定义右键菜单后,通过JS获取点击位置的链接href时返回了空字符串,导致无法触发菜单显示。咱们一步步拆解问题、找到解决方案:
一、问题根源:坐标不匹配
你当前的JS脚本里用了document.elementFromPoint(%f, %f),但传入的坐标是WebView控件内的鼠标坐标,而JS的elementFromPoint方法需要的是相对于文档内容的坐标(要考虑页面滚动、控件内的偏移等),坐标不匹配就会导致找不到正确的<a>元素,自然返回空的href。
二、修正步骤与代码实现
1. 正确转换鼠标坐标
首先要把WebView的鼠标坐标转换成文档内的坐标,JavaFX的WebEngine可以调用JS的window.scrollX和window.scrollY,结合控件内的坐标偏移来计算正确的文档坐标。
2. 修正后的JS脚本与逻辑
同时优化JS脚本,支持向上遍历父元素找<a>(避免右键点击<a>内的子元素时漏判),再配合坐标修正实现完整逻辑:
// 修正后的JS脚本:支持向上遍历父元素查找<a>标签 private final String getHrefJs = "function getLinkAtPoint(x, y) {" + " var elt = document.elementFromPoint(x, y);" + " while (elt && elt.tagName.toLowerCase() !== 'a') {" + " elt = elt.parentElement;" + " }" + " return elt ? elt.getAttribute('href') : '';" + "} getLinkAtPoint(%f, %f);"; // 用于存储当前右键点击的链接URL private String currentLinkUrl; // 处理右键菜单显示的核心方法 private void showMenuIfNeeded(MouseEvent e) throws URISyntaxException { WebEngine engine = webView.getEngine(); // 转换坐标:控件内坐标 + 页面滚动偏移 = 文档内坐标 double docX = e.getX() + (double) engine.executeScript("window.scrollX"); double docY = e.getY() + (double) engine.executeScript("window.scrollY"); String js = String.format(getHrefJs, docX, docY); Object hrefObj = engine.executeScript(js); String href = hrefObj != null ? hrefObj.toString() : ""; // 调试输出,方便排查 System.out.println("执行的JS:" + js); System.out.println("获取到的href:'" + href + "'"); if (!href.isEmpty()) { // 解析为绝对URL(处理相对路径的情况) currentLinkUrl = new URI(engine.getLocation()).resolve(href).toString(); System.out.println("转换后的绝对URL:" + currentLinkUrl); // 显示自定义右键菜单 contextMenu.show(webView, e.getScreenX(), e.getScreenY()); } else { // 点击的不是链接,隐藏菜单 contextMenu.hide(); } } // 绑定右键点击事件 webView.setOnMousePressed(e -> { if (e.getButton() == MouseButton.SECONDARY) { try { showMenuIfNeeded(e); } catch (URISyntaxException ex) { ex.printStackTrace(); contextMenu.hide(); } } else { contextMenu.hide(); } }); // 下载菜单的点击事件 public void fileDownloadContextMenu(Event e) { if (currentLinkUrl != null && !currentLinkUrl.isEmpty()) { System.out.println("开始下载:" + currentLinkUrl); // 这里写入你的下载逻辑代码 } }
三、你的原代码问题排查
你之前的控制台输出显示href是空字符串,核心原因就是坐标不匹配:你传入的53,000000, 150,000000是WebView控件内的坐标,但页面可能有滚动,或者该坐标对应的文档位置根本不是<a>元素,导致JS找不到目标标签,返回空字符串。
按照上面的修正方法,应该就能正确获取到点击的链接URL了!
备注:内容来源于stack exchange,提问作者Katapa
相关产品推荐
相关产品推荐

