一般用electron开发应用都不会使用原生的菜单栏。取消原生菜单栏后就会自定义自己的菜单栏,实现自定义菜单栏的拖拽目前有两种方案。一个是css直接设置(这个推荐,很稳定),第二个是用原生js实现的动态设置窗口的坐标,今天就来测试了一下第二种方法。结论是,可以用但是有很大的局限性,而且拖动过程中还容易卡顿,是不是因为没有防抖节流的原因没有测试。
实现步骤如下:
第一步:渲染层界面设置监听事件,并把实时的窗口位置发送到主进程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>electron</title>
<style>
* {
margin: 0;
padding: 0;
}
.header {
width: 100%;
height: 30px;
background-color: lightslategrey;
}
</style>
</head>
<body>
<div class="header"></div>
<button id="btn">发送</button>
</body>
<script>
const { ipcRenderer } = require("electron");
const btn = document.querySelector("#btn");
const header = document.querySelector(".header");
let isDown = false;
let baseX = 0,
baseY = 0;
header.addEventListener("mousedown", (e) => {
isDown = true;
baseX=e.x
baseY=e.y
// console.log(e.x, e.y);
});
document.addEventListener("mousemove", (e) => {
if(isDown){
const x=e.screenX-baseX
const y=e.screenY-baseY
ipcRenderer.send('move-app',{
postX:x,
postY:y
})
}
});
document.addEventListener("mouseup", (e) => {
isDown=false
});
btn.addEventListener("click", function () {
console.log("btn");
ipcRenderer.send("message", "我是渲染层的信息!");
});
ipcRenderer.on("toRenderer", (e, v) => {
console.log(v);
});
</script>
</html>
第二步:主进程监听事件,并实时设置窗口的位置
const { app, BrowserWindow, ipcMain } = require("electron");
let win = null;
app.on("ready", function () {
console.log("app:ready");
win = new BrowserWindow({
width: 300,
height: 300,
maxWidth: 300,
maxHeight: 300,
minHeight: 300,
minWidth: 300,
show: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
frame: false,
// alwaysOnTop:true
});
// win.setBounds({
// x:10,
// y:100
// })
win.setPosition(10, 10);
win.loadFile("./index.html");
win.once("ready-to-show", function () {
win.show();
});
});
ipcMain.on("message", (e, v) => {
console.log(v);
e.reply("toRenderer", "我是主进程发送回来的信息");
});
ipcMain.on("move-app", (e, v) => {
console.log(v);
const [width,height]=win.getSize()
// win.setPosition(v.postX, v.postY);
// win.setSize(w,h)
win.setBounds({
x:v.postX,
y:v.postY,
width,
height
})
});
需要注意的事项:
必须要在主进程创建窗口设置设置窗口的以下6个属性完全一样。不然会出现拖动时窗口大小会自动变大的情况,出现这一问题的原因是:windows的屏幕设置了“缩放与布局”,经测试,如果不缩放的情况下,不会在拖动时自动放大窗口。实时获取屏幕的dpi再等比例缩放没有测试。总之这种方法还是不建议使用。直接使用css设置会更方便。
width: 300,
height: 300,
maxWidth: 300,
maxHeight: 300,
minHeight: 300,
minWidth: 300,