backspace退出当前页面提示是否退出

本文介绍了一种使用jQuery来监听Backspace按键的方法,并通过一个简单的示例展示了如何在用户按下Backspace键时弹出确认对话框并处理退出操作。
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).keydown(function(event){ 
if(event.keyCode == 8){ //BackSpace的keyCode是8
if(confirm('是否退出')){
//用户退出代码写在这里
alert('退出成功');
}
}
}); 
</script>
这个前端代码的剩余时间倒计时有点问题,过一段时间之后就会卡死<template> <div class="container learnstyle-page" @contextmenu.prevent> <el-card class="box-card"> <div slot="header" class="clearfix" style="font-size: 32px;"> <span style="margin-left: 2%; font-weight: bold;"> {{testPaperInfo.name}} <sys-select v-model="testPaperInfo.paperType" dict-type="paper_type" showType="text" /> (共{{testPaperInfo.questionNumber}}题 合计{{testPaperInfo.mark}}分) </span> <span style="float: right; color: red; margin-right: 2%;">考试剩余时间: {{timeValue}}</span> </div> <question-info ref="questionInfoRef" :showNumberTitle="false" @openWritingBoard="openWritingBoard" :timeOutFlag="timeOutFlag" commitButtonText="提交试卷" @afterCommit="afterCommit" :questionInfoAnswerList="testPaperInfoQuestionList"> </question-info> </el-card> </div> </template> <script> import { mapGetters } from 'vuex' import questionInfo from '@/components/question-info' import { isEmpty } from '@/utils/system-utils' export default { name: 'exam', components: {questionInfo}, data () { return { studentExamTime: 0, // 学生考试用时 studentExamTimer: null, examTime: null, examTimeKey: 'examTime:', // timeInterval: null, timeTarget: null, endTime: null, timeOutFlag: false, // 是否考试时间到 openAnswerFlag: false, leaveNumber: 0, currentQuestion: {}, testPaperInfoQuestionList: [], // 存储用户答题答案及试题答案解析 currentPage: 0, timeValue: '', pageSize: 1, totalCount: 0, openWritingBoardFlag: false, questionTypeList: [], serverTime: null, // 服务器时间 timeDiff: 0, // 服务器时间与本地时间差值 isCommit: false, isFullscreen: true, // 标记是否处于全屏状态 blurTimer: null, // 失去焦点计时器 blurCount: 0, // 失去焦点次数 maxBlurCount: 3, // 最大允许失去焦点次数 warningCount: 0, // 警告次数 maxWarningCount: 5, // 最大警告次数 isPageBlurred: false, // 页面是否失去焦点 blurStartTime: null, // 失去焦点开始时间 warningSubmit: false } }, computed: { ...mapGetters({ testPaperInfo: 'common/getTestPaperInfo' }) }, beforeCreate () { }, mounted () { this.startListener() this.axios.get(this.$httpApi.httpUrl('/student/testPaperInfo/systemTime'), { params: {} }).then(response => { this.isCommit = false this.serverTime = response.data.data // 计算服务器时间与本地时间的差值 this.timeDiff = this.serverTime - new Date().getTime() if (this.testPaperInfo.examTime) { let examTimeObj = sessionStorage.getItem(this.examTimeKey + this.testPaperInfo.id) if (examTimeObj) { this.examTime = parseInt(examTimeObj) } else { this.examTime = this.testPaperInfo.examTime * 60 * 1000 } let now = this.getCurrentTime() if (!isEmpty(this.testPaperInfo.enterDate)) { now = new Date(this.testPaperInfo.enterDate).getTime() } this.endTime = now + this.examTime if (this.testPaperInfo.endTime) { this.endTime = new Date(this.testPaperInfo.endTime).getTime() } this.timeTarget = setInterval(() => { this.startTime(); // 开始倒计时 }, 1000) } this.studentExamTimer = setInterval(() => { this.startCountStudentExamTime() // 开始计算考试时间 }, 1000) this.getPaperQuestionList() }) }, beforeRouteLeave(to, from, next) { // 用户确认离开,提交试卷 // this.$refs.questionInfoRef.commitQuestion(true) next() }, destroyed() { sessionStorage.removeItem(this.examTimeKey + this.testPaperInfo.id) clearInterval(this.timeTarget) clearInterval(this.studentExamTimer) this.endListener() }, methods: { startListener () { // 添加全屏变化事件监听 document.addEventListener('fullscreenchange', this.fullscreenChangeHandler) document.addEventListener('webkitfullscreenchange', this.fullscreenChangeHandler) document.addEventListener('mozfullscreenchange', this.fullscreenChangeHandler) document.addEventListener('MSFullscreenChange', this.fullscreenChangeHandler) // 禁用鼠标右键 document.addEventListener('contextmenu', this.preventRightClick) document.addEventListener('keydown', this.preventDefault); }, endListener () { // 移除全屏变化事件监听 document.removeEventListener('fullscreenchange', this.fullscreenChangeHandler) document.removeEventListener('webkitfullscreenchange', this.fullscreenChangeHandler) document.removeEventListener('mozfullscreenchange', this.fullscreenChangeHandler) document.removeEventListener('MSFullscreenChange', this.fullscreenChangeHandler) // 移除右键禁用事件监听 document.removeEventListener('contextmenu', this.preventRightClick); document.removeEventListener('keydown', this.preventDefault); }, // 处理页面失去焦点 handlePageBlur() { if (this.isCommit) return; this.isPageBlurred = true; this.blurStartTime = new Date().getTime(); // 启动计时器,如果失去焦点超过一定时间则认为切屏 if (this.blurTimer) { clearTimeout(this.blurTimer); } this.blurTimer = setTimeout(() => { if (this.isPageBlurred && !this.isCommit) { this.handlePotentialScreenSwitch(); } }, 500); }, // 处理页面获得焦点 handlePageFocus() { if (this.isCommit) return; this.isPageBlurred = false; if (this.blurTimer) { clearTimeout(this.blurTimer); this.blurTimer = null; } // 如果页面失去焦点时间超过阈值,增加切屏计数 if (this.blurStartTime) { const blurDuration = new Date().getTime() - this.blurStartTime; if (blurDuration > 1000) { // 失去焦点超过2秒 this.blurCount++; this.showBlurWarning(); } this.blurStartTime = null; } }, // 处理页面可见性变化 handleVisibilityChange() { if (document.hidden) { this.handlePageBlur(); } else { this.handlePageFocus(); } // 调用原有的 visibilityChangeEvent 方法 this.visibilityChangeEvent(); }, handleback () { history.pushState(null, null, location.href) }, // 处理可能的切屏行为 handlePotentialScreenSwitch() { this.blurCount++; if (!this.warningSubmit) { this.autoCommitForScreenSwitch(); } // 如果切屏次数超过限制,自动提交试卷 // if (this.blurCount >= this.maxBlurCount) { // this.autoCommitForScreenSwitch(); // } }, // 显示切屏警告 showBlurWarning() { this.warningCount++; this.$message({ // message: `检测到切屏行为,这是第 ${this.blurCount} 次。请注意考试纪律!`, message: `检测到切屏行为,将自动提交试卷!`, type: 'warning', duration: 3000 }); // 如果警告次数过多,自动提交试卷 if (this.warningCount >= this.maxWarningCount) { this.autoCommitForWarnings(); this.warningSubmit = true } }, // 因切屏次数过多自动提交试卷 autoCommitForScreenSwitch() { this.$alert('检测到切屏行为,系统将自动提交试卷。', '考试结束', { confirmButtonText: '确定', type: 'error', callback: () => { this.$refs.questionInfoRef.commitQuestion(true); } }); }, // 因警告次数过多自动提交试卷 autoCommitForWarnings() { this.$alert('检测到多次违规操作,系统将自动提交试卷。', '考试结束', { confirmButtonText: '确定', type: 'error', callback: () => { this.$refs.questionInfoRef.commitQuestion(true); } }); }, preventDefault (e) { // 禁用常见的切屏快捷键 if ( // F5刷新 e.keyCode === 116 || // Ctrl+R (e.ctrlKey && e.keyCode === 82) || // Ctrl+F5 (e.ctrlKey && e.keyCode === 116) || // ESC键 e.keyCode === 27 || // Win键(左右) e.keyCode === 91 || e.keyCode === 92 || // Alt+Tab (e.altKey && e.keyCode === 9) || // Ctrl+Alt+Del (e.ctrlKey && e.altKey && e.keyCode === 46) || // Ctrl+Alt+. (e.ctrlKey && e.altKey && e.keyCode === 190) || // Alt+F4 (e.altKey && e.keyCode === 115) || // 禁用F1、F12 // (e.keyCode === 112 || e.keyCode === 123) || // 禁用Ctrl+W(关闭窗口) (e.ctrlKey && e.keyCode === 87) || // 禁用Win+Tab ((e.keyCode === 91 || e.keyCode === 92) && e.keyCode === 9) || // (e.altKey && (e.key === 'ArrowLeft' || e.key === 'ArrowRight')) || // (e.key === 'Backspace' && e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') ) { e.preventDefault(); e.stopPropagation(); this.warningCount++; return false; } // 禁用Alt键单独按下(防止Alt+Tab) if (e.altKey && e.keyCode !== 9) { e.preventDefault(); e.stopPropagation(); this.warningCount++; return false; } }, handleTouchEnd(event) { if (!this.disableSwipe) return; const touchEndX = event.changedTouches[0].clientX; const touchEndY = event.changedTouches[0].clientY; const diffX = touchEndX - this.touchStartX; const diffY = touchEndY - this.touchStartY; // 判断是否是水平滑动(前进/后退手势) if (Math.abs(diffX) > Math.abs(diffY) && Math.abs(diffX) > 30) { event.preventDefault(); if (diffX > 0) { console.log('右滑后退已被阻止'); } else { console.log('左滑前进已被阻止'); } } }, // 处理触摸移动事件 handleTouchMove(event) { if (this.disableSwipe) { event.preventDefault(); console.log('触摸滑动已被阻止'); } }, // 处理鼠标按下事件 handleMouseDown(event) { this.mouseDownButton = event.button; // 检测侧键(前进/后退) if (this.disableMouseButtons && (event.button === 3 || event.button === 4)) { event.preventDefault(); const buttonName = event.button === 3 ? '后退' : '前进'; console.log(`鼠标${buttonName}键按下已被阻止`); } }, // 处理鼠标释放事件 handleMouseUp(event) { // 检测侧键(前进/后退) if (this.disableMouseButtons && (event.button === 3 || event.button === 4)) { event.preventDefault(); const buttonName = event.button === 3 ? '后退' : '前进'; console.log(`鼠标${buttonName}键释放已被阻止`); } this.mouseDownButton = null; }, // 阻止右键菜单 preventRightClick(event) { event.preventDefault(); return false; }, keyDownHandler (event) { console.log('keyDownHandler', event.keyCode) if (event.key === 'Escape' && this.isFullscreen) { event.preventDefault() this.$confirm('退出全屏将自动提交试卷,是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { // 用户确认退出,提交试卷 this.$refs.questionInfoRef.commitQuestion(true) }).catch(() => { // 用户取消退出,重新进入全屏 }) } }, // 全屏变化事件处理 fullscreenChangeHandler() { // 检查是否退出了全屏模式 const isCurrentlyFullscreen = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement; // 如果之前是全屏状态,现在不是全屏状态,说明用户手动退出了全屏 if (this.isFullscreen && !isCurrentlyFullscreen && !this.isCommit) { this.$refs.questionInfoRef.commitQuestion(true) } this.isFullscreen = !!isCurrentlyFullscreen }, // 处理用户手动退出全屏的情况 handleManualExitFullscreen() { // 如果试卷还未提交,则提示用户并自动提交 if (!this.isCommit) { this.$confirm('退出全屏将自动提交试卷,是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { // 用户确认退出,提交试卷 this.$refs.questionInfoRef.commitQuestion(true) }).catch(() => { // 用户取消退出,重新进入全屏 this.enterFullscreen() }) } }, // 进入全屏模式 enterFullscreen() { const element = document.documentElement; if (element.requestFullscreen) { element.requestFullscreen(); } else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if (element.webkitRequestFullscreen) { element.webkitRequestFullscreen(); } else if (element.msRequestFullscreen) { element.msRequestFullscreen(); } this.isFullscreen = true }, // 退出全屏模式 exitFullscreen() { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } this.isFullscreen = false }, // 获取当前准确时间(基于服务器时间) getCurrentTime() { return new Date().getTime() + this.timeDiff }, openWritingBoard () { this.openWritingBoardFlag = true }, startCountStudentExamTime () { this.studentExamTime++ }, // 监听页面离开事件 visibilityChangeEvent (e) { // 考试中请勿离开当前页面系统将自动提交 if (!this.isCommit) { this.$refs.questionInfoRef.commitQuestion(true) } }, startTime() { if (this.timeValue === '0:00:00' || this.timeValue === '00:00:00') { clearInterval(this.timeTarget) this.$notify({ title: '警告', duration: 3000, message: '考试时间到,系统将自动提交本次考试', type: 'warning' }) setTimeout(() => { this.timeOutFlag = true }, 100) return false } let nowTime = this.getCurrentTime(); let chaTime = this.endTime - nowTime; //倒计时的时间 if (chaTime >= 0) { let d = Math.floor(chaTime / 1000 / 60 / 60 / 24); let h = Math.floor(chaTime / 1000 / 60 / 60 % 24); if (h <= 9) { h = 0 + '' + h } let m = Math.floor(chaTime / 1000 / 60 % 60); if (m <= 9) { m = 0 + '' + m } let s = Math.floor(chaTime / 1000 % 60); if (s <= 9) { s = 0 + '' + s } if (d > 0) { this.timeValue = d + '天' + h + '时' + m + '分' + s + '秒' } else { this.timeValue = h + ':' + m + ':' + s } } this.examTime = this.examTime - 100 // 缓存考试时间,防止刷新页面考试时间仍然不变的问题 sessionStorage.setItem(this.examTimeKey + this.testPaperInfo.id, this.examTime) }, selectQuestion (index) { }, // 答题卡 openAnswerSheet () { this.openAnswerFlag = true }, // 获取试卷试题列表 getPaperQuestionList () { this.axios.get(this.$httpApi.httpUrl('/student/testPaperInfo/selectPaperQuestionById'), { params: { id: this.testPaperInfo.id } }).then(response => { this.testPaperInfoQuestionList = response.data.data this.testPaperInfoQuestionList.forEach(item =>{ let questionType = item.questionType if (questionType !== 1 && questionType !== 6) { this.$set(item, 'studentAnswer', []) // item.studentAnswer = [] 此方式会导致v-model 无法绑定变量 } else { this.$set(item, 'studentAnswer', '') } }) }) }, afterCommit (questionAnswerParam) { if (this.isCommit) { return } this.isCommit = true clearInterval(this.studentExamTimer) let params = { examTime: this.studentExamTime, testPaperInfoId: this.testPaperInfo.id, questionAnswerList: questionAnswerParam } this.axios.post(this.$httpApi.httpUrl('/student/testPaperInfo/commitPaper'), params) .then(response => { // 提交成功后退出全屏模式 this.exitFullscreen(); this.endListener() this.$message.success('提交成功') this.$router.push('examHistory') }) } }, filters: { } } </script> <style scoped> .container.learnstyle-page { width: 100%; padding: 0 8%; margin-top: 1%; } .exam_time { color: red; font-size: 24px; position: relative; left: 30%; bottom: 80% } .back{ color:#ca0000; cursor: pointer; } .text { font-size: 14px; } .oper-btn { position: relative; left: 35%; margin-top: 50px; } .radio-item { line-height: 40px; margin-left: 20px } .item { margin-bottom: 18px; } .clearfix:before, .clearfix:after { display: table; content: ""; } .clearfix:after { clear: both } .box-card p {display: inline} .box-card { width: 100%; } .box-card >>> p {display: inline-block} </style>
08-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值