js如何识别是页面关闭,而非页面刷新

js如何识别是页面关闭,而非页面刷新

      // 离开页面时添加提示
      window.onbeforeunload = (e) => {
        e = e || window.event;
        if (e) {
          e.returnValue = '确定要关闭此窗口吗?';
        }
        return '确定要关闭此窗口吗?';
      };

当前代码无论页面关闭,还是页面刷新都会触发阻止弹框,如何判断只在页面关闭是阻止用户,提示弹框,刷新时不阻止?

以下引用了GPT生成的解答:
要区分页面关闭和页面刷新,可以利用unload事件和beforeunload事件的差异。unload事件在页面关闭时触发,而beforeunload事件在页面关闭或刷新时都会触发。

你可以使用以下代码来判断是否是页面关闭而不是页面刷新:

let isPageRefreshing = false;

window.addEventListener('beforeunload', (e) => {
  if (!isPageRefreshing) {
    e.preventDefault();
    e.returnValue = '确定要关闭此窗口吗?';
  }
});

window.addEventListener('unload', () => {
  isPageRefreshing = true;
});

// 其他刷新页面的代码(例如点击刷新按钮)
function refreshPage() {
  isPageRefreshing = true;
  window.location.reload();
}

在这个代码中,我们引入了一个isPageRefreshing变量来跟踪页面是否正在刷新。当页面关闭时,beforeunload事件会被触发,但只有在isPageRefreshingfalse时才会阻止用户,并显示确认弹框。当页面刷新时,unload事件会被触发,此时我们将isPageRefreshing设为true,以区分页面关闭和页面刷新。

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/167974
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:js实现刷新页面,实现滚动条还停留在上次访问的位置,同时用户在列表页进入详情之后,回来还在之前的浏览位置
  • 除此之外, 这篇博客: 用JS实现 使用动态优先权的进程调度算法模拟中的 详细的步骤和思路全部在代码注释中,保证你看一遍就知道代码的意思,阅读起来没有任何难度 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • //定义一个PCB对象
    function PCB(ID, Priority, Cputime, Alltime, Startblock, BlockTime, state) {
        this.ID = ID //进程ID
        this.Priority = Priority //进程优先级
        this.Cputime = Cputime //进程已占用的事件
        this.Alltime = Alltime //进程需要占用的时间
        this.Startblock = Startblock //进程需阻塞时间
        this.BlockTime = BlockTime //进程阻塞的时间
        this.state = state //进程状态
    }
    //定义五个进程
    let One = new PCB(0, 9, 0, 3, 2, 3, "Start")
    let Two = new PCB(1, 38, 0, 3, -1, 0, "Start")
    let Three = new PCB(2, 30, 0, 6, -1, 0, "Start")
    let Four = new PCB(3, 29, 0, 3, -1, 0, "Start")
    let Five = new PCB(4, 0, 0, 4, -1, 0, "Start")
        //就绪队列
    let readyqueue = []
        //阻塞队列
    let blockqueue = []
        //临时队列,存储初始队列
    let tempqueue = []
        //执行完的队列
    let overqueue = []
        //定义一个数组(队列)
    readyqueue = [One, Two, Three, Four, Five]
        //正在进行的进程
    let runProgress = new PCB()
        // 就绪队列优先权排序
        /** 
         * Sort的排序是按照队列各个元素的Priority(也就是优先权排队的)
         * 每次排完以后,优先权最大的在数组后面,这样每次运行主程序只需要
         * 将最后一个拿出来就是要被运行的进程
         * 
         */
    function Sort(start) {
        //sort函数 里面自己写一个函数,用来比较对象内的属性(默认的sort往往是不能够使用的)
        function sortBy(field) {
            return function(a, b) {
                return a[field] - b[field];
            }
        }
        start.sort(sortBy("Priority"));
        return start
    }
    
    //定义一个展示的界面
    function showWindow(start) {
        let str1 = ''
        let str2 = ''
        let str3 = ""
        let str4 = ""
        let str5 = ""
        let str6 = ""
        let str7 = ""
        for (let i = 0; i < start.length; i++) {
            str1 = str1 + "     " + start[i].ID;
            str2 = str2 + "     " + start[i].Priority;
            str3 = str3 + "     " + start[i].Cputime;
            str4 = str4 + "     " + start[i].Alltime;
            str5 = str5 + "    " + start[i].Startblock;
            str6 = str6 + "     " + start[i].BlockTime;
            str7 = str7 + "   " + start[i].state;
        }
        console.log("------------------------------------------------")
        console.log("| ID        " + str1 + "   |")
        console.log("| Priority  " + str2 + "   |")
        console.log("| Cputime   " + str3 + "   |")
        console.log("| AllTime   " + str4 + "   |")
        console.log("| StackBlock " + str5 + " |")
        console.log("| BlockTime " + str6 + "   |")
        console.log("| State   " + str7 + "   |")
        console.log("#################################################")
        showID("blockqueue", blockqueue)
        showID("overqueue", overqueue)
        console.log("------------------------------------------------")
    }
    
    function showID(str1, arr) {
        let str = ""
        for (let i = 0; i < arr.length; i++) {
            str += " " + arr[i].ID
        }
        console.log(str1 + "里面的进程有:" + str)
    }
    //阻塞队列更新
    /** 
     * 阻塞队列的更新一共有两个参数,因为阻塞中的进程,如果他的阻塞时间(BlockTime)等于0
     * 意味着它的阻塞时间已经到了,就需要到就绪队列中
     * 进入就绪队列以后就要对就绪队列进行重新排序找出优先权最大的那个
     */
    function blockqueueUpdata(blockqueue, readyqueue) {
        if (blockqueue.length != 0) {
            for (item of blockqueue) {
                item.BlockTime--
                    if (item.BlockTime == 0) {
                        readyqueue.push(item)
                        blockqueue.pop()
                        readyqueue = Sort(readyqueue)
                        break;
                    }
            }
        }
    }
    //就绪队列更新
    /** 
     * 对就绪队列的更新,需要明白最后一个进程是不能更新的
     * 因为最后一个进程是优先权最大的那个,那个进程是正在运行的进程,严格意义上说它不算是就绪队列的
     * 所以我们只需要对除了最后一个元素的其他元素进行优先权+1的操作
     */
    function readyqueueUpdata(readyqueue) {
        for (let i = 0; i <= readyqueue.length - 2; i++) {
            readyqueue[i].Priority++
        }
    }
    //index记录运行个时间片
    let index = 0
        //运行一个时间片
    function run(readyqueue) {
        readyqueue = Sort(readyqueue) //运行之前 先对就绪队列排序
        console.log("第" + index + "次")
            //这个地方展示的结果是每次运行前的结果,变化后的结构在下一次展示中能看到
        showWindow(readyqueue)
            /*** 
             * 每运行一次  正在运行的进程的优先权-3  所需时间片-1  已占用CPU时间+1
             */
        readyqueue[readyqueue.length - 1].Priority -= 3
        readyqueue[readyqueue.length - 1].Alltime -= 1
        readyqueue[readyqueue.length - 1].Cputime += 1
            //运行完以后需要对就绪队列和阻塞队列进行更新
        readyqueueUpdata(readyqueue)
        blockqueueUpdata(blockqueue, readyqueue)
            /*每次运行都需要把运行进程的的Startblock-1
            Startblock=n表示 该进程在运行n个时间片就会进入阻塞队列
            */
        readyqueue[readyqueue.length - 1].Startblock -= 1
            /*查看就绪队列最后一个(也就是刚刚执行完的优先权最大的那个进程)
                    他的时间片是否已经运行完了,如果他的Alltime==0 意味着它
                    运行结束,就可以进入结束队列,不需要在就绪队列呆着(不需要
                        进行任何操作,其他进程运行与它无关)
            */
        if (readyqueue[readyqueue.length - 1].Alltime == 0) {
            console.log(readyqueue[readyqueue.length - 1].ID)
            readyqueue[readyqueue.length - 1].state = "Finish"
            overqueue.push(readyqueue.pop())
        }
        // 谁的StartBlock==0 就意味该进程需要进入阻塞队列,不能在就绪队列呆着
        //因为每次对StartBlock-1 都是对就绪队列最后一个进行操作,所以这个只需要比较最后一个
        if (readyqueue.length > 0) {
            if (readyqueue[readyqueue.length - 1].Startblock == 0) {
                readyqueue[readyqueue.length - 1].state = "Block"
                blockqueue.push(readyqueue.pop())
            }
        }
        readyqueue = Sort(readyqueue)
        index++
    }
    //主函数 k的取值我是随便选的  主要判断就是readyqueue.length
    //如果等于0就结束操作,你这k 可以为任何值(需要和while一样就行)
    function main(readyqueue) {
        let k = 0
        while (k < 5) {
            run(readyqueue)
            k = 0
            if (readyqueue.length == 0) {
                k = 5
            }
        }
    }
    main(readyqueue)
    
  • 您还可以看一下 李广川老师的NW.JS 跨平台桌面客户端新手快速入门实战课程中的 课程介绍小节, 巩固相关知识点