网站转桌面应用

工具 刘宇帅 5天前 阅读量: 66

这两天工作又比较忙,没看书,没思考,写一篇简单的技术教程。其实我是不想写这种的,因为本身没啥技术含量,只是把写的东西整理一下,即提高不了技术,也没有思考深度,以后要少写,这类还是以笔记的形式记录到博客即可。

最近公司在推jira,但是整体感觉用起来很困难。主要因为是日常浏览器用的会比较多,基本上chrome上都有四五十个tab标签,经常会切到其它tab看东西,然后每次想要找jira的时候都不太好找,所以就想把jira单独打成一个桌面应用,整体操作和心理感受上感觉都简单很多。

electron介绍

Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库。 Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用来实现这一目的。

详细教程

新建一个项目并安装electron electron-builder两个依赖

mkdir desktopdemo
cd desktopdemo
cnpm init
cnpm i electron --save-dev
cnpm i electron-builder --save-dev

添加构建命令到package.json

  "build": {
    "appId": "com.example.app",
    "mac": {
      "target": [
        "dmg",
        "zip"
      ]
    },
    "win": {
      "target": [
        "nsis",
        "zip"
      ]
    }
  },
  "scripts": {
    "start": "electron .",
    "dist": "electron-builder"
  },

新建index.js

(async () => {
    const {app, BrowserWindow, BrowserView, ipcMain, webContents} = require("electron");
    const {join} = require("path");

    await app.whenReady()

    const window = new BrowserWindow({
        webPreferences: {
            sandbox: false,
            nodeIntegration: true,
            contextIsolation: false
        }
    });

    await window.loadFile(join(__dirname, "./titlebar.html"));
    const browserView = new BrowserView({
        webPreferences: {
            sandbox: true,
            nodeIntegration: false
        }
    });
    window.setBrowserView(browserView);
 // const contents = window.webContents;
 // contents.openDevTools(); //打开调试工具

    const contentBounds = window.getContentBounds();
    browserView.setBounds({x: 0, y: 50, width: contentBounds.width, height: contentBounds.height - 30});
    browserView.setAutoResize({width: true, height: true});

    await browserView.webContents.loadURL("https://www.liuyushuai.com/"); // 更换自己的域名
    window.webContents.send("sendId", browserView.webContents.id);
    window.webContents.on('did-finish-load', function () {
        window.webContents.send("sendId", browserView.webContents.id);
    })

    browserView.webContents.on("did-navigate", () => {
        window.webContents.send("canNav", browserView.webContents.canGoBack(), browserView.webContents.canGoForward());
    });

    ipcMain.on("goBack", (e, webContentsId) => {
        const wc = webContents.fromId(webContentsId);
        if (wc && wc.canGoBack()) {
            wc.goBack();
        }
    });

    ipcMain.on("goForward", (e, webContentsId) => {
        const wc = webContents.fromId(webContentsId);
        if (wc && wc.canGoForward()) {
            wc.goForward();
        }
    });
})();

新建titlebar.html

<html>

<body>
<div id="toolbar">
    <button id="back" class="button back" disabled>go back</button>
    <button id="forward" class="button next" disabled>go forward</button>
</div>

<script src="./renderer.js"></script>
<style>
    #toolbar {
        height: 50px;
    }

    a {
        margin: 10px;
    }

    .active {
        color:#555 !important;
    }

    .button {
        display: inline-block;
        position: relative;
        color: #888;
        text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
        text-decoration: none;
        text-align: center;
        padding: 8px 12px;
        font-size: 12px;
        font-weight: 700;
        font-family: helvetica, arial, sans-serif;
        border-radius: 4px;
        border: 1px solid #bcbcbc;
        -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
        background-image: -webkit-linear-gradient(top, #fff 0%, #efefef 60%, #e1dfe2 100%);
        background-image: -moz-linear-gradient(top, #fff 0%, #efefef 60%, #e1dfe2 100%);
        background-image: -o-linear-gradient(top, #fff 0%, #efefef 60%, #e1dfe2 100%);
        background-image: -ms-linear-gradient(top, #fff 0%, #efefef 60%, #e1dfe2 100%);
        background-image: linear-gradient(top, #fff 0%, #efefef 60%, #e1dfe2 100%);
    }
    .button:hover {
        color: #555;
    }
    .button:active,
    .button:active:after,
    .button:active:before {
        -webkit-box-shadow: none;
        box-shadow: none;
        /* Back Button */
    }
    .button.back {
        border-left: none;
    }
    .button.back:after {
        content: '';
        position: absolute;
        height: 50%;
        width: 15px;
        border-left: 1px solid #bcbcbc;
        background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        background-image: -ms-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        background-image: linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        left: -5px;
        top: 1px;
        -webkit-transform: skew(-35deg, 0);
        -moz-transform: skew(-35deg, 0);
        -o-transform: skew(-35deg, 0);
        -ms-transform: skew(-35deg, 0);
        transform: skew(-35deg, 0);
    }
    .button.back:before {
        content: '';
        position: absolute;
        height: 48%;
        width: 15px;
        border-left: 1px solid #bcbcbc;
        bottom: 1px;
        left: -5px;
        -webkit-transform: skew(35deg, 0);
        -moz-transform: skew(35deg, 0);
        -o-transform: skew(35deg, 0);
        -ms-transform: skew(35deg, 0);
        transform: skew(35deg, 0);
        background-image: -webkit-linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        background-image: -moz-linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        background-image: -o-linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        background-image: -ms-linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        background-image: linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        -webkit-box-shadow: -2px 1px 2px rgba(100, 100, 100, 0.1);
        box-shadow: -2px 1px 2px rgba(100, 100, 100, 0.1);
        /* Next Button */
    }
    .button.next {
        border-right: none;
    }
    .button.next:after {
        content: '';
        position: absolute;
        height: 48%;
        width: 15px;
        border-right: 1px solid #bcbcbc;
        background-image: -webkit-linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        background-image: -moz-linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        background-image: -o-linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        background-image: -ms-linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        background-image: linear-gradient(top, #f0f0f0 0%, #efefef 10%, #e1dfe2 100%);
        right: -5px;
        bottom: 1px;
        -webkit-transform: skew(-35deg, 0);
        -moz-transform: skew(-35deg, 0);
        -o-transform: skew(-35deg, 0);
        -ms-transform: skew(-35deg, 0);
        transform: skew(-35deg, 0);
        -webkit-box-shadow: 2px 1px 2px rgba(100, 100, 100, 0.1);
        box-shadow: 2px 1px 2px rgba(100, 100, 100, 0.1);
    }
    .button.next:before {
        content: '';
        position: absolute;
        background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        background-image: -ms-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        background-image: linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 1%, #f0f0f0 100%);
        height: 50%;
        width: 15px;
        border-right: 1px solid #bcbcbc;
        top: 1px;
        right: -5px;
        -webkit-transform: skew(35deg, 0);
        -moz-transform: skew(35deg, 0);
        -o-transform: skew(35deg, 0);
        -ms-transform: skew(35deg, 0);
        transform: skew(35deg, 0);
    }
</style>
</body>

</html>

新建 renderer.js

const {ipcRenderer} = require("electron");

const backButton = document.getElementById("back");
const forwardButton = document.getElementById("forward");

let webContentsId = -1;
ipcRenderer.on("sendId", (e, id) => {
    webContentsId = id;
});

ipcRenderer.on("canNav", (e, canBack, canForward) => {
    backButton.disabled = !canBack;
    forwardButton.disabled = !canForward;
    backButton.classList = canBack ? "button back active":"button back";
    forwardButton.classList = canForward?"button next active":"button next";
});

backButton.onclick = () => {
    ipcRenderer.send("goBack", webContentsId);
};

forwardButton.onclick = () => {
    ipcRenderer.send("goForward", webContentsId);
};

启动

cnpm start

image-20220617235502676

打包

cnpm run dist

可以看到dist目录下打包好的包

image-20220617235815508

提示

功能待开通!


暂无评论~