electron 無邊框窗口拖拽移動問題及解決辦法
electron 無邊框窗口拖拽移動問題記錄及解決辦法
在做一款uTools的插件,懸浮文本
窗口是沒有標題欄的,所以需要找一個地方可以拖動移動位置
就開始了接下來的踩坑記錄
項目結(jié)構(gòu)
只是一個簡單的容器元素,一個多行文本框
容器元素加一個內(nèi)邊距,然后這個內(nèi)邊距區(qū)域就是我理想的可拖動位置
<body> <div id="container"> <textarea id="content" spellcheck="false"></textarea> </div> </body>
實現(xiàn)流程
webkit-app-region
首個版本,我采用CSS很簡單便實現(xiàn)了
當(dāng)時是用 Mac 開發(fā)測試的,一切運行良好
#container { -webkit-app-region: drag; padding: 10px; cursor: move; }
隔天到 Win 上看效果
發(fā)現(xiàn)拖動雖然正常,但是光標樣式?jīng)]有了
鼠標放在邊框位置不會變成移動的光標
經(jīng)查閱,設(shè)置了-webkit-app-region: drag;
的元素,不會在響應(yīng)鼠標事件了(mac上測試的時候正常的)
so,需要繼續(xù)改了
鼠標事件
沒有簡便辦法了,就只好自己寫個鼠標拖拽事件了
按下記錄下鼠標相對于窗口的位置
鼠標移動后計算出窗口新的位置
窗口新位置
=窗口當(dāng)前位置
+鼠標新的相對位置
-鼠標原來的相對位置
主進程 (因為是uTools
插件開發(fā),和electron
原始代碼的監(jiān)聽不一樣)
ipcRenderer.on('move', (event, x, y) => { ubWindow.setPosition(x, y) }) // 初始化 ipcRenderer.sendTo(ubWindow.webContents.id, 'init')
webPreferences
的preload
const { ipcRenderer } = require('electron') let winId ipcRenderer.on('init', (event) => { winId = event.senderId window.init() }) window.move = (x, y) => { ipcRenderer.sendTo(winId,'move',x, y) }
頁面js
let moveIng = false let startX = 0 let startY = 0 const move = (event) => { if (!moveIng) return const x = window.screenX + event.clientX - startX const y = window.screenY + event.clientY - startY window.move(x, y) } //綁定拖拽移動事件 document.addEventListener('mousedown', (event) => { if (event.button === 0 && event.target.tagName !== 'TEXTAREA') { moveIng = true startX = event.clientX startY = event.clientY document.addEventListener('mousemove', move) } }) document.addEventListener('mouseup', (event) => { if (!moveIng) return document.removeEventListener('mousemove', move) moveIng = false })
測試,Win和Mac拖拽正常,光標正常
But,換電腦在測試時,發(fā)現(xiàn)某個Win的電腦移動窗口時,窗口尺寸會不停的變大
甚至只要鼠標按在窗口上,尺寸都可能會改變
so,繼續(xù)改吧
縮放
經(jīng)過多次測試和查閱
最終把問題定位在Win的縮放與布局
該選項如果是100%
測試一點問題都沒有
如果每次拖動尺寸會發(fā)生改變,那我們就不再使用setPosition
改用setBounds
每次調(diào)整位置時直接將尺寸也傳遞進去,修改下代碼
主進程
ipcRenderer.on('moveBounds', (event, x, y, width, height) => { if (event.senderId == ubWindow.webContents.id) { let newBounds = { x: parseInt(x), y: parseInt(y), width: parseInt(width), height: parseInt(height), } ubWindow.setBounds(newBounds) } }) // 初始化 ipcRenderer.sendTo(ubWindow.webContents.id, 'init')
webPreferences
的preload
const { ipcRenderer } = require('electron') let winId ipcRenderer.on('init', (event) => { winId = event.senderId window.init() }) window.moveBounds = (x, y, width, height) => { ipcRenderer.sendTo(winId, 'moveBounds', x, y, width, height); }
頁面js
let moveIng = false let startX = 0 let startY = 0 let lastWidth = 0 let lastHeight = 0 const move = (event) => { if (!moveIng) return const x = window.screenX + event.clientX - startX const y = window.screenY + event.clientY - startY window.moveBounds(parseInt(x), parseInt(y), lastWidth, lastHeight) } //綁定拖拽移動事件 document.addEventListener('mousedown', (event) => { if (event.button === 0 && event.target.tagName !== 'TEXTAREA') { moveIng = true startX = parseInt(event.clientX) startY = parseInt(event.clientY) lastWidth = parseInt(window.outerWidth) lastHeight = parseInt(window.outerHeight) document.addEventListener('mousemove', move) } }) document.addEventListener('mouseup', (event) => { if (!moveIng) return document.removeEventListener('mousemove', move) moveIng = false })
調(diào)整后Win和Mac測試均正常
但如果拖動過快,仔細觀察,窗口有時會閃爍
而且文本框中的內(nèi)容有時會變成選中狀態(tài)
嗯~ o(* ̄▽ ̄*)o
暫時就醬吧
有大神知道更好解決方案的話可以貼出來觀摩下
補充:
Electron無邊框自定義窗口拖動
解決方案
<header class="absolute" style="left:0px;top:0px;width:100%;height:48px;background-color:red;padding:0px;margin:0px;"> <div class="absolute" style="left:0px;top:0px;width:100%;height:100%;-webkit-app-region:drag"> <button style="width:200px;height:100px;-webkit-app-region:no-drag;" @click="console.log('abc')">點我</button> </div> </header>
首先外部可拖拽區(qū)域設(shè)置:-webkit-app-region:drag;
如果想要里面的按鈕可點擊,僅需要設(shè)置按鈕不可拖拽就行:-webkit-app-region:drag;
到此這篇關(guān)于electron 無邊框窗口拖拽移動問題記錄及解決辦法的文章就介紹到這了,更多相關(guān)electron 無邊框窗口拖拽移動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
webpack4手動搭建Vue開發(fā)環(huán)境實現(xiàn)todoList項目的方法
這篇文章主要介紹了webpack4手動搭建Vue開發(fā)環(huán)境實現(xiàn)todoList項目的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05javaScript年份下拉列表框內(nèi)容為當(dāng)前年份及前后50年
本文介紹的這個javaScript年份下拉列表框內(nèi)容為當(dāng)前年份及前后50年,默認顯示當(dāng)前年份,大家可以學(xué)習(xí)下2014-05-05JS實現(xiàn)的一個簡單的Autocomplete自動完成例子
這篇文章主要介紹了JS實現(xiàn)的一個簡單的Autocomplete自動完成例子,需要的朋友可以參考下2014-04-04Javascript獲取隨機數(shù)的實現(xiàn)方法
下面小編就為大家?guī)硪黄狫avascript獲取隨機數(shù)的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06