JavaScript如何防止頁(yè)面退格鍵回退
在一個(gè)網(wǎng)頁(yè)中,當(dāng)我們?cè)谳斎肟騼?nèi)輸入文字或者進(jìn)行密碼輸入時(shí),我們并不希望用戶通過按下退格鍵來操作歷史記錄和回退到上一個(gè)頁(yè)面。因此,我們往往需要編寫代碼來阻止這個(gè)默認(rèn)行為。本文將介紹如何使用JS來實(shí)現(xiàn)這個(gè)過程,并展示此方法可以在不同的場(chǎng)景下調(diào)用。
什么是退格鍵
最初的Unix終端是Teletype ASR33,由紙帶穿孔機(jī)以及紙帶閱讀機(jī)和鍵盤組成。Backspace和Delete并不屬于該鍵盤上的按鍵
在鍵入內(nèi)容的時(shí)候如果出錯(cuò),則需要按下^(ctrl)+H向teletype發(fā)送一個(gè)退格命令,使得穿孔機(jī)移回之前的位置,然后按下Rubout鍵再發(fā)送一個(gè)刪除命令才能做到刪除對(duì)應(yīng)位置內(nèi)容
之后為了方便開始制造帶有backspace按鍵的終端,同時(shí)完成退格和刪除兩個(gè)功能
后來Rubout鍵被改名為Delete,一些Unix公司決定在鍵盤中加入Delete鍵(用于刪除一個(gè)字符),這些公司決定用Delete代替^+H代表退格。因此,情況變成了一些鍵盤可以按下Backspace刪除字符,另一些要按下Delete。
對(duì)于現(xiàn)在的鍵盤來講,實(shí)際情況是有Backspace鍵時(shí)按下后則會(huì)觸發(fā)退格加刪除兩個(gè)操作,此時(shí)的Delete鍵的作用只對(duì)應(yīng)刪除這一個(gè)操作,因此Backspace鍵刪除的都是光標(biāo)之前的字符,Delete鍵刪除的是光標(biāo)之后的字符;如果沒有Backspace鍵則用Delete鍵來代替(也是退格加刪除兩個(gè)操作)。
思路概述
首先,通過鍵盤事件檢查用戶的按鍵,判斷對(duì)于的鍵是否是“退格鍵”。如果是,則阻止默認(rèn)行為,即不允許回退。該過程可以分為以下幾步:
- 注冊(cè)鍵盤事件監(jiān)聽器;
- 獲取當(dāng)前被按下的鍵名稱;
- 判斷是否對(duì)應(yīng)“退格鍵”;
- 阻止事件的默認(rèn)行為。
具體實(shí)現(xiàn)
document.onkeydown = function(event) { var e = event || window.event; var keyCode = e.keyCode || e.which; // 判斷是否為退格鍵 if (keyCode == 8) { if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } } }
以上代碼展示了具體實(shí)現(xiàn)過程。其中,我們通過keyCode
或which
獲取當(dāng)前鍵位,使用if語句判斷是否為退格鍵(退格鍵的keycode為8),如果是則執(zhí)行preventDefault()
阻止默認(rèn)行為,否則放行。
兼容性
該方法與不同的瀏覽器兼容性良好。以上代碼中處理退格鍵的keyCode
屬性已被所有現(xiàn)代瀏覽器所支持,同時(shí)也被IE等老舊瀏覽器所支持。
但是,為了保證屏幕能夠?qū)崟r(shí)響應(yīng)用戶的操作,我們還應(yīng)該考慮到一些其他因素。例如:
- 輸入框焦點(diǎn)問題;
- 操作歷史記錄問題(比如在Firefox上,無法通過上述方式堵住history.back())。
處理焦點(diǎn)問題
因?yàn)槲覀冎幌胱柚褂脩粼诋?dāng)前輸入框輸入時(shí)使用退格鍵進(jìn)行“回退”操作,因此如果用戶焦點(diǎn)不在一個(gè)輸入框內(nèi)(例如按下Tab鍵)而按下退格鍵,我們可以不做任何處理。下面展示了如何根據(jù)焦點(diǎn)狀態(tài)來判斷是否進(jìn)行回退處理。(在本例中,我們選擇使用jQuery庫(kù))
$(document).on('keydown', function (event) { if (event.keyCode == 8) { var doPrevent = false; var target = event.target; if (target.isContentEditable || (target.nodeName.toLowerCase() == 'input' && (target.type.toLowerCase() == 'text' || target.type.toLowerCase() == 'password' || target.type.toLowerCase() == 'email'))) { // 在輸入框或可編輯區(qū)域 doPrevent = false; } else { doPrevent = true; } if (doPrevent) { event.preventDefault(); } } });
處理history.back()問題
如果用戶使用退格鍵作為history.back()方法的替代品,那么我們需要捕獲該事件并進(jìn)行處理。在這種情況下,我們不應(yīng)該阻止跳轉(zhuǎn),而是在回退前彈出一個(gè)警告框,讓用戶來確認(rèn)是否想要撤銷操作。
$(document).on("keydown", function(event) { var doPrevent = false; if ((event.ctrlKey || event.metaKey) && (event.keyCode == 78 || event.keyCode == 82)) { doPrevent = true; } if (event.keyCode == 8) { var target = event.target; if (target.isContentEditable || (target.nodeName.toLowerCase() == 'input' && (target.type.toLowerCase() == 'text' || target.type.toLowerCase() == 'password' || target.type.toLowerCase() == 'email'))) { // 在輸入框或可編輯區(qū)域 doPrevent = false; } else { doPrevent = true; } } if (doPrevent) { event.preventDefault(); window.history.back(); if (typeof window.history.back.callback === "function") { window.history.back.callback(); } else { window.history.back.callStack = window.history.back.callStack || []; window.history.back.callStack.push(window.history.back); } setTimeout(function() { var r = confirm("確認(rèn)要現(xiàn)在離開該頁(yè)面嗎?"); if (r == true) { window.location = "/logout"; } else { window.history.forward(); if (window.history.back.callStack.length > 0) { var c = window.history.back.callStack.pop(); c(); } } }, 100); return true; } });
如上代碼所示,我們將用戶的操作記錄壓入一個(gè)callStack數(shù)組中,并彈出確認(rèn)框來防止過快跳轉(zhuǎn)影響用戶體驗(yàn)。如果用戶選擇“確認(rèn)”,則返回到主頁(yè)并進(jìn)行相關(guān)處理;否則,程序?qū)⒃赾all stack數(shù)組中找到最有一個(gè)未執(zhí)行的回調(diào)函數(shù),再次執(zhí)行。
在 Vue 中使用
方案一:自定義指令
Vue v-on
指令支持警告修飾符 .prevent
來停止事件冒泡并防止熱鍵。我們可以創(chuàng)建一個(gè)自定義指令來觸發(fā)該修飾符。
在 main.js
文件中注冊(cè)指令:
Vue.directive('prevent-back', { bind: function (el, binding, vnode) { var handler = function (event) { if (event.keyCode === 8) { event.preventDefault(); vnode.elm.dispatchEvent(new Event('input')); } }; el.addEventListener('keydown', handler); el.addEventListener('blur', function() { el.removeEventListener('keydown', handler); }); } });
在模板中使用自定義指令:
<template> <div> <input type="text" v-prevent-back /> </div> </template>
方案二:Vue Mixin
Vue Mixin 可以讓我們?cè)诮M件中混入同樣的數(shù)據(jù)和方法,從而復(fù)用代碼。我們可以創(chuàng)建一個(gè)全局的 Mixin,在需要阻止回退鍵的組件中混入該 Mixin。
在 main.js
文件中定義 Mixin:
Vue.mixin({ methods: { preventBackspace: function(event) { if (event.keyCode === 8) { event.preventDefault(); } }, addKeyListener: function() { window.addEventListener('keydown', this.preventBackspace, true); }, removeKeyListener: function() { window.removeEventListener('keydown', this.preventBackspace, true); } } })
在組件中混入 Mixin:
import Vue from 'vue'; export default { mixins: [Vue.mixin], mounted() { this.addKeyListener(); }, destroyed() { this.removeKeyListener(); } }
總結(jié)
本文詳細(xì)介紹了如何實(shí)現(xiàn)屏蔽頁(yè)面退格鍵回退的方法。同時(shí),我們討論了如何在不同環(huán)境下確保其兼容性和正確性。通過使用jQuery庫(kù)和一些看似簡(jiǎn)單但微不足道的技巧,我們成功地在幾個(gè)關(guān)鍵點(diǎn)上解決了各種問題。我相信讀完這篇文章后,你已經(jīng)能夠輕松地在其他網(wǎng)站上使用此方法并應(yīng)用到自己的項(xiàng)目中去啦!
到此這篇關(guān)于JavaScript如何防止頁(yè)面退格鍵回退的文章就介紹到這了,更多相關(guān)JavaScript防止退格鍵回退內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS 根據(jù)子網(wǎng)掩碼,網(wǎng)關(guān)計(jì)算出所有IP地址范圍示例
這篇文章主要介紹了JS 根據(jù)子網(wǎng)掩碼,網(wǎng)關(guān)計(jì)算出所有IP地址范圍,涉及IP地址、子網(wǎng)的正則驗(yàn)證,子網(wǎng)掩碼計(jì)算等相關(guān)操作技巧,需要的朋友可以參考下2016-09-09javascript實(shí)現(xiàn)倒計(jì)時(shí)(精確到秒)
本文給大家分享的是個(gè)人項(xiàng)目中使用的javascript實(shí)現(xiàn)的精確到秒級(jí)的倒計(jì)時(shí)代碼,十分的實(shí)用,有需要的小伙伴可以參考下。2015-06-06處理JavaScript值為undefined的7個(gè)小技巧
這篇文章主要介紹了處理JavaScript值為undefined的7個(gè)小技巧,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07