// 离开页面时添加提示
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
事件会被触发,但只有在isPageRefreshing
为false
时才会阻止用户,并显示确认弹框。当页面刷新时,unload
事件会被触发,此时我们将isPageRefreshing
设为true
,以区分页面关闭和页面刷新。
//定义一个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)