Atom Electron webview 上下文菜单,获取点击目标
Atom Electron webview contextmenu, get click target
所以我正在开发一个新项目,我们想使用 Electron 为我们的用户创建一个桌面应用程序。
问题是我需要在 webview 元素上自定义上下文菜单。
到目前为止,我的进度是可以在 webview 上创建上下文菜单,但是我无法访问点击下的内容。 :)
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());
});
那么,当发生右键单击时,我如何才能获得例如 link 的 href
属性,以便为用户创建一个新选项卡。
选项卡运行良好,创建新的网络视图,选择活动的等。我只需要从 links 获取 urls ...:D
好的,我明白了,所以我要回答我的问题。
我的解决方案是webview的preload属性。我创建了一个 *.js 文件,它在加载时被注入到 webview 中。此文件包含点击事件的事件侦听器,并通过电子中的 "ipcRenderer" 向主要 window.
发送基于事件目标的 "ipc" 消息
这样我可以为不同的元素创建不同的上下文菜单,例如:a、输入、文本区域等...
注入的 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 的父视图中 window 我监听我的自定义 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)
},
}))
所以我正在开发一个新项目,我们想使用 Electron 为我们的用户创建一个桌面应用程序。
问题是我需要在 webview 元素上自定义上下文菜单。
到目前为止,我的进度是可以在 webview 上创建上下文菜单,但是我无法访问点击下的内容。 :)
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());
});
那么,当发生右键单击时,我如何才能获得例如 link 的 href
属性,以便为用户创建一个新选项卡。
选项卡运行良好,创建新的网络视图,选择活动的等。我只需要从 links 获取 urls ...:D
好的,我明白了,所以我要回答我的问题。
我的解决方案是webview的preload属性。我创建了一个 *.js 文件,它在加载时被注入到 webview 中。此文件包含点击事件的事件侦听器,并通过电子中的 "ipcRenderer" 向主要 window.
发送基于事件目标的 "ipc" 消息这样我可以为不同的元素创建不同的上下文菜单,例如:a、输入、文本区域等...
注入的 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 的父视图中 window 我监听我的自定义 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)
},
}))