Electron开发要点

RoderickQiu

2019-01-24 17:43:56

Personal

还是想起来做一份electron开发要点录,不知道做不做得全。 包括一切Electron开发中可能用到的东西,诸如node,javascript或者bootstrap。 不时会来更新一下。 ------ # 0. 资料大全 - https://blog.avocode.com/4-must-know-tips-for-building-cross-platform-electron-apps-f3ae9c2bffff (need proxy) - https://electronjs.org/docs - https://getbootstrap.com/docs/4.2/getting-started/introduction/ - http://www.fontawesome.com.cn/faicons/ - https://api.jquery.com/ # 1. 允许自动播放音频 在Chrome的新版本里面,自动播放音频被禁止了。因而基于Chromium的Electron中也就是一样的了。 解决方案: ```javascript app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required');// 允许自动播放音频 ``` 在主进程中使用。 # 2. electron-store获取布尔值时的注意事项 ```javascript if (store.get("top") == true || store.get("top") == undefined) win.setAlwaysOnTop(true) ``` 当你的项目还未定义时,其值为*undefined*,**特判永远重要**。 **附录:** - `store.get("name")`获取值 - `store.set("name","val")`设置值 - `store.delete("name")`删除值 # 3. 菜单 无论是顶栏菜单还是右键菜单(有框窗口的),在打包之后都会消失不见。因此我们需要自己设置。 如: ```javascript if (process.platform === 'darwin') { var template = [{ label: 'wnr', submenu: [{ label: 'Quit', accelerator: 'CmdOrCtrl+Q', click: function () { app.quit(); } }] }, { label: 'Edit', submenu: [{ label: 'Undo', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' }, { label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' }, { type: 'separator' }, { label: 'Cut', accelerator: 'CmdOrCtrl+X', selector: 'cut:' }, { label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' }, { label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' }, { label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' }] }]; var osxMenu = menu.buildFromTemplate(template); menu.setApplicationMenu(osxMenu); } ``` 可以设置Content Menu。 # 4. 主进程中对于win的控制 ```javascript if (win != null) { win.reload() } ``` 设置win之前从来都要判断win存不存在,类似的,在yDic中查询显示一本词典中的某个值如音标前要判断是否有音标,免得出事情。 # 5. 对于预设函数 ```javascript function (response, checkboxChecked) { if (checkboxChecked) { shell.openExternal("https://github.com/RoderickQiu/wnr/releases/latest"); } }) ``` 纵使function的第一个位置的变量并没有用,也要放在那里占位,否则就是对函数的错误重载。 当然,如果官方提供了重载,那就是再好不过了。 # 6. 打包之后文件位置更换问题 ```javascript tray = new Tray('./res/icons/iconWin.ico') ``` 当我未打包时,此程序运行正常;当我已打包时,则此程序运行错误。 ```javascript const path = require('path') tray = new Tray(path.join(__dirname, '/res/icons/iconWin.ico')) ``` 调用node的path功能才是正确姿势。 # 7. devDependencies & dependencies ```json "dependencies": { "electron-store": "^2.0.0", "request": "^2.88.0", "cheerio": "^1.0.0-rc.2" }, "devDependencies": { "electron": "^4.0.2", "electron-builder": "^20.38.5" }, ``` electron和electron-builder等在打包后就不再需要的东西属于devDependencies。 # 8. electron-builder的设置 ```json "build": { "win": { "target": ["dir"], "icon": "res/icons/iconWin.ico" } } ``` - target要设置成dir,因为我们还要放东西进去的,现在编译白费力气。 - icon要设置,否则就是electron默认icon了。 # 9. 同一个HTML文件中不能两次引用同一个node库或建立同名变量 ```markup <script src="updater.js"></script> <script> var ipc = require('electron').ipcRenderer; function about() { ipc.send("about"); } </script> ``` 当updater.js中也`var ipc = require('electron').ipcRenderer`时,以上代码非法。 # 10. input元素只允许输入数字 ```markup <input name="loop" id="loop" placeholder="loop for how many times" type="number" onkeypress="return (/[0-9]/.test(String.fromCharCode(event.keyCode)))" style="ime-mode:Disabled" class="small" required /> ``` 主要的有效代码是`onkeypress="return (/[0-9]/.test(String.fromCharCode(event.keyCode)))" style="ime-mode:Disabled"`。 # 11. js为html元素赋值时位置的关系 ```markup <span id="wordTitle"></span> <script> $("#wordTitle").val("Example"); </script> ``` script元素必须加载在html元素的后面,否则将会赋值失败。当然,我们也可以使用`$(document).ready(function(){...});`。 还有以下需要注意: - `$("#wordTitle")`中的#不能忘,否则就不是id而是标签了。 - `.val()`适用于input,对于其他元素,应使用`.html()`。 # 12. style覆盖 ```markup <link rel="stylesheet" type="text/css" href="res/lib/bootstrap.min.css" /> <link rel="stylesheet" type="text/css" href="style.css" /> ``` 有时bootstrap中的一些量并不合适,这时候我们可以再放一个style在下面,覆盖掉bootstrap的样式。 注意一定只能放在下面。 # 13. jQuery选择器和Electron冲突 ```markup if (typeof module === 'object') { window.module = module; module = undefined; } ``` 在Electron中使用jQuery会遇到`$`的冲突情况,在此时这段神器代码将会发挥功用。 # 14. Electron的relaunch ```javascript ipcMain.on('relauncher', function () { app.relaunch(); app.exit(0) }) ``` 需要注意的是部分Electron功能并没有想象中那么简单。如`relaunch()`就不能直接使程序重启,而只是注册了重启事件,还是需要先关闭程序,重启事件才会运行。 # 15. HTML获得GET传递值 ```javascript var $_GET = (function () { var url = window.document.location.href.toString(); var u = url.split("?"); if (typeof (u[1]) == "string") { u = u[1].split("&"); var get = {}; for (var i in u) { var j = u[i].split("="); get[j[0]] = j[1]; } return get; } else { return {}; } })(); var title = decodeURI($_GET['title']); ``` 以上的代码可以获取`index.html?title=example`中的example。 # 16. setInterval并不能真正暂停代码运行 ```javascript var int; function ender() { window.clearInterval(int); $("#work-rest").text(""); $("#now-timing").text("End!"); warninggiver(0); isclockworking = 0; $("#stopper").text(""); } function clock() { t = new Date().getTime(); if (method == 1) seconds = parseInt((worktime - t + starttime) / 1000); else seconds = parseInt((resttime - t + starttime) / 1000); if (seconds > 0) { hours = parseInt(seconds / 3600); minutes = parseInt((seconds - hours * 3600) / 60); seconds = seconds - hours * 3600 - minutes * 60; $("#now-timing").text(hours + "h " + minutes + "min " + seconds + "s"); } else { times++; if (times < loop * 2) { starttime = new Date().getTime(); themechanger(); } else if (times == loop * 2) { ender(); } } } int = self.setInterval("clock()", 10); minimizer(); ``` 以上的代码会让`clock()`在一段时间中每隔10ms运行一次,但并不会在`clock()`停止运行之前不运行`minimizer()`。 正确的方式是: ```javascript var x = self.setInterval("y()", 1000); function y(){ window.clearInterval(x); z(); } ``` 这段代码将会停止一秒(此处1000为毫秒,显然是个为了和时间戳保持单位相同而采取的举措),然后再去运行`z()`。 # 17. Electron在外部打开网页 ```markup <a href="javascript:require('electron').shell.openExternal('https://roderickqiu.scris.top/')" class="rest">Roderick Qiu</a> ``` `shell.openExternal(link)`方法可以在外部打开网页。 # 18. 关于表单的样式 表单的样式默认的一般都不好看,因此搜索“名称+美化”寻找解决方案是必然。 如: ```css input{ display: inline-block; line-height: inherit; margin: 0rem; padding: 1px 0px; outline: none; border: none; } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button{ -webkit-appearance: none; } input::-webkit-input-placeholder { color: #999999; transition: color.5s; } input:focus::-webkit-input-placeholder, input:hover::-webkit-input-placeholder { color: #999999c2; transition: color.5s; } ``` 以上代码可以帮助建立一个纯净的,只有输入框,且选中时其提示文本会颜色变淡的number型input元素,就像wnr中使用的那个一样。 # 19. flex布局居中的注意事项 全局设置: ```css html, body{ width: 100%; min-height: 100%; display: -webkit-flex; display: -ms-flexbox; display: flex; align-items: center;/* center in v/h */ } ``` html: ```markup <body class="mx-auto flex-column"> <main role="main" class="flex-shrink-0 align-content-center"> <div class="container-fluid text-center"> ... </div> </main> </body> ``` 以上方案虽不是最好的,但是绝对能用。 如果在布局中有需要固定位置的元素,css里添加个类,`position: absolute`解决一切问题。 # 20. CSS中使用@media标签进行响应式控制 ```css #footer{ position: absolute; bottom: 5px; text-align: center; } @media(max-height:600px){ #footer{ position: relative; } } ``` 则在高度比较大时,footer固定在底部;高度比较小的时候就不固定了以免和正文挤在一起。 # 21. 无边框窗口的拖动问题 - 对于`html, body`,`-webkit-app-region: drag;/* let the app draggable */`。 - 对于内容元素,`-webkit-app-region: no-drag;/* let it clickable */ -webkit-user-select: text;`。 - 对于UI,`-webkit-app-region: no-drag;/* let it clickable */ -webkit-user-select: none;`。 # 22. Electron设置任务栏进度条的方式 ```cpp ipcMain.on("progress-bar-set", function (event, message) { if (win != null) win.setProgressBar(1 - message) }) ``` 需要说明的是win.setProgressBar(-1)可以清除进度条,此时message应该设置为2。 # 23. Electron安装慢的解决方案 [链接](https://www.jianshu.com/p/2f07642bfe7e) # 24. Electron等node扩展安装时没有权限的问题 一般来讲,关掉杀软和ide,用管理员命令行可以解决。 `--verbose` 大法好。 # 25. 只允许同时运行一个程序 ```javascript const gotTheLock = app.requestSingleInstanceLock(); if (!gotTheLock) app.quit()// 只允许同时运行一个wnr ``` # 26. Asar-Unpack ``` "build": { "asarUnpack": [ "./node_modules/node-notifier/vendor/**" ], } ``` ------ 差不多就是以上了。