最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Atom Electron webview contextmenu, get click target - Stack Overflow

programmeradmin2浏览0评论

So I'm working on a new project and we would like to create a desktop application for our users using Electron.

The problem is that I need custom contextmenus on the webview elements.

My progress so far that I can create contextmenus over the webview, but I cannot access the content under the click. :)

index.html:

<webview id="webViewDefault" class="active" src="" 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());
    });

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.

The tabs are working great, creating new webviews, selecting the active ones etc. I just need to get the urls, from the links ...: D

So I'm working on a new project and we would like to create a desktop application for our users using Electron.

The problem is that I need custom contextmenus on the webview elements.

My progress so far that I can create contextmenus over the webview, but I cannot access the content under the click. :)

index.html:

<webview id="webViewDefault" class="active" src="http://example." 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());
    });

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.

The tabs are working great, creating new webviews, selecting the active ones etc. I just need to get the urls, from the links ...: D

Share Improve this question edited Feb 26, 2019 at 20:49 Daniel Turcich 1,8343 gold badges27 silver badges48 bronze badges asked May 12, 2017 at 9:49 LyimmiLyimmi 1231 silver badge8 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

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)
  },
}))

Okay I figured it out, so I'm going to answer my question.

My solution for the problem is the webview's preload attribute. I created a *.js file which is injected in to the webview on load. 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.

This way I can create different contextmenus for different elemnts e.g: a, input, textarea etc...

Injected 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:

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 e up with a better solution I'll edit this.

发布评论

评论列表(0)

  1. 暂无评论