• Electron学习笔记(三)


    相关笔记

    笔记说明

    文本为学习《Electron 实战 入门、进阶与性能优化 刘晓伦 著》时所记录的笔记 主要将书本上的案例运行一遍,针对原理部分并无相关记录。笔记记录于 2023年9月。

    五、界面

    1、获取 webContents 实例

    (1)通过窗口对象的 webContent 属性获取 webContent 实例:
    let webContent = win.webContents;
    
    (2)获取当前激活窗口的 webContents 实例:
    const { webContents } = require('electron');
    let webContent = webContents.getFocusedWebContents();
    
    (3)在渲染进程中获取当前窗口的 webContents 实例:
    const { remote } = require('electron');
    let webContent = remote.getCurrentWebContents();
    
    (4)通过 id 获取 webContents 实例:

    创建窗口时 Electron 会为相应的 webContents 设置一个整型的 id

    const { webContents } = require('electron');
    let webContent = webContents.fromId(yourId);
    
    (5)遍历应用内的 webContents 对象:
    const { webContents } = require('electron');
    let webContentArr = webContents.getAllWebContents();
    
    for (let webContent of webContentArr) {
        if (webContent.getURL().includes('baidu')) {
            console.log('do what you want');
        }
    }
    

    2、页面加载事件及触发顺序

    通过 webContents 对象监听以下事件:

    顺序
    事件
    说明
    1did-start-loading页面加载过程中的第一个事件。如果该事件在浏览器中发生,那么意味着此时浏览器tab页的旋转图标开始旋转,如果页面发生跳转,也会触发该事件
    2page-title-updated页面标题更新事件,事件处理函数的第二个参数为当前的页面标题
    3dom-ready页面中的dom加载完成时触发
    4did-frame-finish-load框架加载完成时触发。页面中可能会有多个 iframe ,所以该事件可能会被触发多次,当前页面为 mainFrame
    5did-finish-load当前页面加载完成时触发。注意,此事件在 did-frame-finish-load 之后触发
    6page-favicon-updated页面 icon 图标更新时触发
    7did-stop-loading所有内容加载完成时触发。如果该事件在浏览器中发生,那么意味着此时浏览器tab页的旋转图标停止旋转

    3、页面跳转事件

    通过 webContents 对象监听以下事件:

    事件
    说明
    will-redirect当服务端返回了一个301或者302跳转后,浏览器正准备跳转时,触发该事件。Electron可以通过 event.preventDefault() 取消此事件,禁止跳转继续执行
    did-redirect-navigation当服务端返回了一个301或者302跳转后,浏览器开始跳转时,触发该事件。Electron不能取消此事件。此事件一般发生在 will-redirect 之后
    did-start-navigation用户点击了某个跳转链接或者JavaScript设置了 window.location.href 属性,页面(包含页面内任何一个 frame 子页面)发生页面跳转之时,会触发该事件。此事件一般发生在 will-navigate 之后
    will-navigate用户点击了某个跳转链接或者JavaScript设置了 window.location.href 属性,页面发生跳转之前,触发该事件。然而当调用 webContents.loadURL 和 webContents.back 时并不会触发该事件。此外,当更新 window.location.hash 或者用户点击了一个锚点链接时,也并不会触发该事件
    did-navigate-in-page当更新 window.location.hash 或者用户点击了一个锚点链接时,触发该事件
    did-frame-navigate主页面(主页面 main frame 也是一个 frame )和子页面跳转完成时触发。当更新 window.location.hash 或者用户点击了一个锚点链接时,不会触发该事件
    did-navigate主页面跳转完成时触发该事件(子页面不会)。当更新 window.location.hash 或者用户点击了一个锚点链接时,并不会触发该事件

    4、页面缩放

    通过 webContents 的 setZoomFactor 方法设置页面的缩放比例:

    const { remote } = require("electron");
    let webContents = remote.getCurrentWebContents();
    webContents.setZoomFactor(0.3)
    let factor = webContents.getZoomFactor();
    console.log(factor); //输出0.3
    

    通过 webContents 的 setZoomLevel 方法设置页面的缩放等级:

    const { remote } = require("electron");
    let webContents = remote.getCurrentWebContents();
    webContents.setZoomLevel(-6)
    let level = webContents.getZoomLevel();
    console.log(level); //输出-6
    

    5、页面容器

    BrowserView: 用于在页面中嵌入其他页面。它依托 BrowserWindow 存在,可以绑定到 BrowserWindow 的一个具体的区域。

    let view = new BrowserView({
        webPreferences: { 
            // preload
        }
    });
    win.setBrowserView(view);
    
    let size = win.getSize();
    // setBounds:绑定到窗口的具体区域
    view.setBounds({
        x: 0,
        y: 80,
        width: size[0],
        height: size[1] - 80
    });
    // setAutoResize:设置自己在宽度和高度上自适应父窗口的宽度和高度的变化
    view.setAutoResize({
        width: true,
        height: true
    });
    view.webContents.loadURL(url);
    

    隐藏 BrowserView:

    方法一:

    // 隐藏
    win.removeBrowserView(view);
    // 显示
    win.addBrowserView(view);
    

    方法二:

    //显示
    view.webContents.insertCSS('html{display: block}'); 
    //隐藏
    view.webContents.insertCSS('html{display: none}'); 
    

    6、脚本注入

    在使用 Vue CLI ⇡ 搭建完项目的基础上:

    (1) 通过 preload 参数注入脚本

    public/ 目录下新建一个文件 preload.js ,文件内容如下:

    const fs = require('fs');
    
    window.onload = function () {
        // 修改图片
        document.querySelector('#s_lg_img').src = 'https://pic.netbian.com/uploads/allimg/230714/004250-1689266570104f.jpg';
    
        // 可以在脚本内使用 Node.js API
        // fs.appendFileSync('./test.txt','xxx',err =>{})
    }
    

    修改 src/background.js 文件:

    const path = require('path');
    
    // 修改请求头 User-Agent(应用中所有的页面加载请求都会使用此 User-Agent)
    // app.userAgentFallback = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0';
    
    async function createWindow() {
    
        const win = new BrowserWindow({
            width: 800,
            height: 600,
            webPreferences: {
                // 加载 preload.js 文件
                preload: path.join(__static, 'preload.js'),
            }
        });
    
        win.loadURL('https://www.baidu.com/');
    
        // 单独设置请求头 User-Agent
        // win.webContents.loadURL('https://www.baidu.com/', {
        //     userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox / 68.0'
        // })
    }
    '
    运行

    注意:考虑到安全问题,nodeIntegration 不建议开启

    运行程序:

    运行结果


    (2) 通过 executeJavaScript 注入脚本

    说明:executeJavaScript 方法适用于注入代码量较少的情况。

    修改 src/background.js 文件:(效果同上)

    async function createWindow() {
        
        const win = new BrowserWindow({
            width: 800,
            height: 600,
            webPreferences: {
            }
        });
    
        win.loadURL('https://www.baidu.com/');
    
        win.webContents.executeJavaScript("document.querySelector('#s_lg_img').src = 'https://pic.netbian.com/uploads/allimg/230714/004250-1689266570104f.jpg'");
    }
    '
    运行

    (3) 通过 insertCSS 注入样式

    核心代码如下:

    win.loadURL('https://www.baidu.com/');
    
    // 将目标页面的背景颜色修改为 黑色
    win.webContents.insertCSS("html, body { background-color: #000 !important; }");
    

    7、使用 Javascript 控制动画

    在使用 Vue CLI ⇡ 搭建完项目的基础上:

    此时使用 JavaScript 的动画 API —— Web Animations API 控制动画。

    修改 src/App.vue 文件中的 template 内容:

    <template>
        <div id="app">
            <img alt="Vue logo" src="./assets/logo.png" ref="logo">
            <HelloWorld msg="Welcome to Your Vue.js App" />
    
            
            <button @click="pause">暂停button>
            <button @click="play">开启button>
            <button @click="reverse">重播button>
        div>
    template>
    

    修改 src/App.vue 文件中的 script 内容:

    <script>
    import HelloWorld from './components/HelloWorld.vue'
    
    export default {
        name: 'App',
        components: {
            HelloWorld
        },
        data() {
            return {
                keyframes: [{
                    transform: "translate(0px, -120px)",
                    opacity: 0
                }, {
                    transform: "translate(0px, 0px)",
                    opacity: 1
                }],
                {/* 动画相关的属性控制 */}
                options: {
                    iterations: 1,
                    delay: 0,
                    duration: 800,
                    easing: "ease"
                },
                myAnimation: '',
            }
        },
        mounted() {
            this.myAnimation = this.$refs.logo.animate(this.keyframes,this.options);
        },
        methods: {
            pause() {
                this.myAnimation.pause();
            },
            play() {
                this.myAnimation.play();
            },
            reverse() {
                this.myAnimation.reverse();
            },
        }
    }
    </script>
    

    参数说明:

    此处的 keyframes 相当于定义一个动画,规定动画的开始和结束的位置及透明度。

    keyframes: [{
        transform: "translate(0px, -120px)",
        opacity: 0
    }, {
        transform: "translate(0px, 0px)",
        opacity: 1
    }]
    '
    运行

    此处的 options 用于设置动画的相关属性。
    iterations --> animation-iteration-count (规定动画被播放的次数)
    delay --> animation-delay (规定动画何时开始)
    duration --> animation-duration (动画持续时间)
    easing -->(运动曲线)

    options: {
        iterations: 1,
        delay: 0,
        duration: 800,
        easing: "ease"
    }
    
  • 相关阅读:
    浪潮云海首席科学家张东:面向一云多芯的系统设计方法
    Spring Boot 集成 MinIO 实现文件上传、下载和删除
    阿里P8大牛用实例跟你讲明白“Java 微服务架构实战”
    专利评估的方法与流程!
    【力扣hot100】刷题笔记Day17
    【python与数据分析】Pandas统计分析基础
    js-array数组-slice-splice
    新起点丨MeterSphere开源持续测试平台v2.0发布
    华为ce12800交换机m-lag(V-STP模式)配置举例
    MySQL系列索引专题
  • 原文地址:https://blog.csdn.net/qq_45897239/article/details/138664282