简体   繁体   English

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

[英]Atom Electron webview contextmenu, get click target

So I'm working on a new project and we would like to create a desktop application for our users using Electron. 因此,我正在进行一个新项目,我们想使用Electron为我们的用户创建一个桌面应用程序。

The problem is that I need custom contextmenus on the webview elements. 问题是我需要在webview元素上使用自定义contextmenus。

My progress so far that I can create contextmenus over the webview, but I cannot access the content under the click. 到目前为止,我的进度可以在Web视图上创建上下文菜单,但是单击后无法访问内容。 :) :)

index.html: index.html:

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

renderer.js 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());
    });

So how can I get for example a link's href attribute when a right click happens, so I can create a new tab for the user. 因此,当发生右键单击时,如何获取链接的href属性,因此可以为用户创建一个新标签页。

The tabs are working great, creating new webviews, selecting the active ones etc. I just need to get the urls, from the links ...: D 这些选项卡工作得很好,可以创建新的Webview,选择活动的Webview,等等。我只需要从链接中获取URL,即可:... D

Okay I figured it out, so I'm going to answer my question. 好吧,我知道了,所以我要回答我的问题。

My solution for the problem is the webview's preload attribute. 我针对该问题的解决方案是webview的preload属性。 I created a *.js file which is injected in to the webview on load. 我创建了一个* .js文件,该文件在加载时被注入到Webview中。 This file contains the event listeners for the click events and sends an "ipc" message based on the events target via the "ipcRenderer" in electron to the main window. 该文件包含单击事件的事件侦听器,并通过电子中的“ ipcRenderer”将基于事件目标的“ ipc”消息发送到主窗口。

This way I can create different contextmenus for different elemnts eg: a, input, textarea etc... 这样我可以为不同的元素创建不同的上下文菜单,例如:a,输入,textarea等。

Injected js: 注入的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);

In the webview's parent window I listen for my custom ipc messages and handle them as needed: 在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());
    }
});

I'm not 100% sure this is the nicest way to solve this issue, but for the time being it work if I come up with a better solution I'll edit this. 我不是100%肯定这是解决此问题的最好方法,但是暂时来说,如果我想出一个更好的解决方案,我将对此进行编辑。

Store your desired information in a global state store, and then access it from within your context menu click event. 将所需的信息存储在全局状态存储中,然后从上下文菜单单击事件中访问它。

For Example 例如

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