electron 无边框窗口拖拽移动问题及解决办法

 更新时间:2023年12月22日 15:22:18   作者:IT老大哥  
在做一款uTools的插件,悬浮文本,窗口是没有标题栏的,所以需要找一个地方可以拖动移动位置,本文给大家介绍electron 无边框窗口拖拽移动问题及解决办法,感兴趣的朋友一起看看吧

electron 无边框窗口拖拽移动问题记录及解决办法

在做一款uTools的插件,悬浮文本

image

窗口是没有标题栏的,所以需要找一个地方可以拖动移动位置

就开始了接下来的踩坑记录

项目结构

只是一个简单的容器元素,一个多行文本框

容器元素加一个内边距,然后这个内边距区域就是我理想的可拖动位置

<body>
  <div id="container">
    <textarea id="content" spellcheck="false"></textarea>
  </div>
</body>

实现流程

webkit-app-region

首个版本,我采用CSS很简单便实现了

当时是用 Mac 开发测试的,一切运行良好

#container {
	-webkit-app-region: drag;
	padding: 10px;
	cursor: move;
}

隔天到 Win 上看效果

发现拖动虽然正常,但是光标样式没有了

鼠标放在边框位置不会变成移动的光标

经查阅,设置了-webkit-app-region: drag;的元素,不会在响应鼠标事件了(mac上测试的时候正常的)

so,需要继续改了

鼠标事件

没有简便办法了,就只好自己写个鼠标拖拽事件了

按下记录下鼠标相对于窗口的位置

鼠标移动后计算出窗口新的位置

窗口新位置=窗口当前位置+鼠标新的相对位置-鼠标原来的相对位置

主进程 (因为是uTools插件开发,和electron原始代码的监听不一样)

ipcRenderer.on('move', (event, x, y) => {
  ubWindow.setPosition(x, y)
})
// 初始化
ipcRenderer.sendTo(ubWindow.webContents.id, 'init')

webPreferencespreload

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,换电脑在测试时,发现某个Win的电脑移动窗口时,窗口尺寸会不停的变大

甚至只要鼠标按在窗口上,尺寸都可能会改变

so,继续改吧

缩放

经过多次测试和查阅

最终把问题定位在Win的缩放与布局

该选项如果是100%测试一点问题都没有

如果每次拖动尺寸会发生改变,那我们就不再使用setPosition改用setBounds

每次调整位置时直接将尺寸也传递进去,修改下代码

主进程

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')

webPreferencespreload

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

调整后Win和Mac测试均正常

但如果拖动过快,仔细观察,窗口有时会闪烁

而且文本框中的内容有时会变成选中状态

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

首先外部可拖拽区域设置:-webkit-app-region:drag;
如果想要里面的按钮可点击,仅需要设置按钮不可拖拽就行:-webkit-app-region:drag;

到此这篇关于electron 无边框窗口拖拽移动问题记录及解决办法的文章就介绍到这了,更多相关electron 无边框窗口拖拽移动内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javscript 数组扁平化的实现

    javscript 数组扁平化的实现

    这篇文章主要介绍了javscript 数组扁平化的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • js根据鼠标移动速度背景图片自动旋转的方法

    js根据鼠标移动速度背景图片自动旋转的方法

    这篇文章主要介绍了js根据鼠标移动速度背景图片自动旋转的方法,实例分析了javascript操作鼠标与图片的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • js实现小星星游戏

    js实现小星星游戏

    这篇文章主要为大家详细介绍了js实现小星星游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 在百度知道团队中快速审批新成员的js脚本

    在百度知道团队中快速审批新成员的js脚本

    每天都有大量网友申请加入我的团队,于是审核团队新成员成了一个费力气的活儿,在此情况下,我写了个脚本,自动计算他们的回答采纳率,采纳率低于20%的自动打勾 选中,等级太低的人也自动打勾选中
    2014-02-02
  • javaScript中封装的各种写法示例(推荐)

    javaScript中封装的各种写法示例(推荐)

    这篇文章主要给大家介绍了关于javaScript中封装的各种写法的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-07-07
  • 从初始化到遍历解析JavaScript中数组避坑指南

    从初始化到遍历解析JavaScript中数组避坑指南

    数组是 JS 开发中最常用的数据结构,但你真的会用吗,本文带你彻底搞懂数组初始化、遍历方法,以及那个让无数人踩坑的 let vs var 闭包问题
    2026-02-02
  • 使用JavaScript字符串解决回文数的方案详解

    使用JavaScript字符串解决回文数的方案详解

    这篇文章主要介绍了使用JavaScript字符串解决回文数的方案,JavaScript中的字符串是一种数据类型,用于表示文本数据,字符串可以包含任意字符序列,包括字母、数字、符号和空格,灵活掌握字符串的解决问题思想,巧用字符串解决回文数,需要的朋友可以参考下
    2024-05-05
  • 详解CocosCreator华容道数字拼盘

    详解CocosCreator华容道数字拼盘

    这篇文章主要介绍了详解CocosCreator华容道数字拼盘,对华容道感兴趣的同学,看完之后,可以回去亲手试一下
    2021-04-04
  • 微信小程序实现时间进度条功能

    微信小程序实现时间进度条功能

    这篇文章主要为大家详细介绍了微信小程序实现时间进度条功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • JS获取页面input控件中所有text控件并追加样式属性

    JS获取页面input控件中所有text控件并追加样式属性

    使用jquery来在页面加载时获取页面input控件中所有text控件并添加样式,由于其他方式比较麻烦所以就想通过在页面加载的时候将要改动的text找到并添加属性,感兴趣的你可以参考下,希望可以帮助到你
    2013-02-02

最新评论