繁体   English   中英

Atom Electron Webview上下文菜单,获取点击目标

[英]Atom Electron webview contextmenu, get click target

因此,我正在进行一个新项目,我们想使用Electron为我们的用户创建一个桌面应用程序。

问题是我需要在webview元素上使用自定义contextmenus。

到目前为止,我的进度可以在Web视图上创建上下文菜单,但是单击后无法访问内容。 :)

index.html:

<webview id="webViewDefault" class="active" src="http://example.com" minwidth="100%" minheight="100%" partition="somePartition" nodeintegration allowpopups></webview>

renderer.js

    const electron = require('electron');
    const Menu = electron.remote.Menu;

//Create contextmenu template
    const WebViewMenu = Menu.buildFromTemplate([{
        label: 'Button 1', click(){
            console.log('Button 1 clicked');
        }
    },
        {type: 'separator'}, {
            label: 'Button 2', click(){
                console.log('Button 2 clicked');
            }
        }
    ]);

//get webview
    let defaultWebview = document.getElementById("webViewDefault");

//add event listner
    defaultWebview.addEventListener("contextmenu", (event) => {
        const t = event.srcElement.id.split('-');
        WebViewMenu.popup(electron.remote.getCurrentWindow());
    });

因此,当发生右键单击时,如何获取链接的href属性,因此可以为用户创建一个新标签页。

这些选项卡工作得很好,可以创建新的Webview,选择活动的Webview,等等。我只需要从链接中获取URL,即可:... D

好吧,我知道了,所以我要回答我的问题。

我针对该问题的解决方案是webview的preload属性。 我创建了一个* .js文件,该文件在加载时被注入到Webview中。 该文件包含单击事件的事件侦听器,并通过电子中的“ ipcRenderer”将基于事件目标的“ ipc”消息发送到主窗口。

这样我可以为不同的元素创建不同的上下文菜单,例如:a,输入,textarea等。

注入的js:

const {ipcRenderer} = require('electron');

document.addEventListener('contextmenu', function (e) {
    e = e || window.event;
    let msg = {
            tagName: e.target.tagName || e.srcElement.tagName,
            text: e.target.textContent || text.innerText,
            href: e.target.getAttribute("href")
        };

    if (msg.tagName.toLowerCase() === 'a' && msg.href.substring(0, 1) !== "#") {
        ipcRenderer.send("webview-context-link", msg);
    }
}, false);

在webview的父窗口中,我听自定义ipc消息并根据需要进行处理:

const electron = require('electron'),
        Menu = electron.remote.Menu,
        ipc = electron.ipcRenderer;

electron.remote.ipcMain.on("webview-context-link", (event, data) => {
    if (url = validateUrl(data.href)) {
        const WebViewMenu = Menu.buildFromTemplate([{
            label: 'Open in new tab', click(){
                addNewTab(url)
            }
        }]);

        WebViewMenu.popup(electron.remote.getCurrentWindow());
    }
});

我不是100%肯定这是解决此问题的最好方法,但是暂时来说,如果我想出一个更好的解决方案,我将对此进行编辑。

将所需的信息存储在全局状态存储中,然后从上下文菜单单击事件中访问它。

例如

// Instantiate a Global Store
const globalStore = {
  eventTargetHref = null
}

// Set value inside your DOM node event listener
aDOMnode.addEventListener('contextmenu', (event) => {
  event.preventDefault()
  globalStore.eventTargetHref = event.target.href
  aContextMenu.popup(remote.getCurrentWindow())
}

// Access value from your context menu click event
aContextMenu.append(new MenuItem({
  label: 'Open In New Tab',
  click() {
    addNewTab(globalStore.eventTargetHref)
  },
}))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM