媒介
头几天用户反映在录入材料时一不小心错按Backspace键,就会直接回退到是一个页面,致使之前辛辛苦苦录入的材料悉数丧失了。哦?竟然另有这类状况。下面我们来一同讨论一下吧!
Windows体系下独占的行动
Windows下的IE、FireFox和Chrome 52之前的浏览器,当核心不在一个可编辑的元素上时,按Backspace
键就会回退到上一个页面,按Shift
+Backspace
键则会行进到下一个页面。
而Chrome 52今后的浏览器则屏障了Backspace
和Shift
+Backspace
的上述行动,而是采纳Alt
+Left
完成回退和Alt
+Right
完成行进。假如想恢复Backspace
回退,则须要装置Go Back With Backspace的Extension才行。
关于FireFox而言,我们能够设置Backspace
和Shift
+Backspace
的行动。
在地址栏输入
about:config
在搜刮框输入
browser.backspace_action
,然后设置项目值即可。有3个可选项0
,示意Backspace
和Shift
+Backspace
的行动对应页面回退和行进(Windows下的默许值)
1
,示意Backspace
和Shift
+Backspace
的行动对应页面向下转动和向上转动2
或其他值,示意不响应Backspace
和Shift
+Backspace
(Ubuntu16下的默许值)
注重:Linux和OS X下的浏览器按Backspace
和Shift
+Backspace
不会触发页面的回退和行进。
怎样应对
计划一:页面跳转时弹出二次确认
经由过程beforeunload
事宜完成页面跳转时弹出二次确认模态窗,让用户有忏悔的时机。但会截断其他一般跳转的操纵流畅性,在确切没有办法时才运用!
计划二:直接屏障
屏障Backspace
和Shift
+Backspace
的默许行动,仅当核心落在可编辑地区中时才临时作废屏障。
那末哪些算是能取得核心的可编辑地区呢?就下面这些咯!!
input[type=text]:not([readonly])
input[type=password]:not([readonly])
input[type=number]:not([readonly])
input[type=email]:not([readonly])
input[type=url]:not([readonly])
input[type=search]:not([readonly])
input[type=tel]:not([readonly])
textarea:not([readonly])
[contenteditable]:not([readonly])
就是说当核心落在上述相符划定规矩的元素上时,按Backspace
和Shift
+Backspace
的默许行动就不是页面跳转,因而不必屏障掉。
附加功用
如今我们的目标是页面不会由于用户误操纵而革新,致使页面数据丧失。这里有两个组合键同样会的致使页面革新
ctrl
+r
革新当前页面,可被阻挠;ctrl
+w
封闭当前窗体或标签页,没法阻挠。
代码时候.js
;window.nobsgb || (function(exports){
var started = false
exports.start = function(){started = true}
exports.stop = function(){started = false}
var KEYCODE = {
BACKSPACE: 8,
R: 82
}
// 推断type是不是不受阻挠
var isEscapableType = function(rEscapableTypes){
return function(type){
return rEscapableTypes.test(type)
}
}(/text|textarea|tel|email|number|search|password|url/i)
// 推断标签是不是不受阻挠
var isEscapableTag = function(rEscapableTag){
return function(tag){
return rEscapableTag.test(tag)
}
}(/input|textarea/i)
// 推断是不是设置为content editable
var isContentEditable = function(el){
return el.isContentEditable
}
// 推断是不是为不受阻挠的Backspace
var isEscapableBackspace = function(el){
return or(isEscapableTag(el.tagName)
&&
or(!('type' in el)
, ('type' in el) && isEscapableType(el.type) && !el.readOnly)
, isContentEditable(el))
}
var isCtrlR = function(e, keycode){
return e.ctrlKey && KEYCODE.R === keycode
}
var isArray = function(x){
return /Array/.test(Object.prototype.toString.call(x))
}
var getEvt = function(e){
return e || window.event
}
var getTarget = function(e){
return e.target || e.srcElement
}
var getKeycode = function(e){
return e.keyCode || e.which
}
var preventDefault = function(e){
e.preventDefault && e.preventDefault()
e.returnValue = false
return false
}
var listen = function(listen){
return function(evtNames, handler){
if (!isArray(evtNames)){
evtNames = [evtName]
}
var i = 0
, len = evtNames.length
for (; i < len; ++i){
listen(evtNames[i], handler)
}
}
}(function(evtName, handler){
if (or(document['addEventListener'] && (document['addEventListener'].apply(document, arguments) || true)
, document['attachEvent'] && (document['attachEvent'].apply(document, arguments) || true))){
document['on'+evtName] = handler
}
})
var or = function(){
var ret = false
, i = 0
, len = arguments.length
for (; !ret && i < len; ++i){
ret = ret || arguments[i]
}
return ret
}
var handler = function(e){
if (!started) return true
var evt = getEvt(e)
, el = getTarget(evt)
, keyCode = getKeycode(evt)
if (or(KEYCODE.BACKSPACE === keyCode && !isEscapableBackspace(el)
, isCtrlR(evt, keyCode))){
return preventDefault(evt)
}
}
listen(['keydown'], handler)
}(window.nobsgb = {}))
代码时候.cljs
core.cljs
(ns nobsgb.core
(:require [nobsgb.dom :as dom]
[nobsgb.pred :as pred]))
(def started false)
(defn ^:export start []
(set! started true))
(defn ^:export stop []
(set! started false))
(defn handler
"keydown事宜响应函数"
[e]
(when started
(let [evt (dom/get-evt e)
el (dom/get-el evt)
key-code (dom/get-key-code evt)
ctrl-key (dom/get-ctrl-key evt)
read-only (dom/get-read-only el)
type (dom/get-type el)
content-editable (dom/get-content-editable el)
tag (dom/get-tag el)]
(if-not
(pred/escapable?
key-code read-only type tag content-editable ctrl-key)
(dom/prevent-default evt)
true))))
(defonce init
(#(dom/listen! js/document "keydown" handler)))
dom.cljs
(ns nobsgb.dom)
(defn get-evt
[e]
(if (some? e) e (.event js/window)))
(defn get-el
[e]
(let [el (.-target e)]
(if (some? el) el (.-srcElement e))))
(defn get-key-code
[e]
(.-keyCode e))
(defn get-ctrl-key
[e]
(.-ctrlKey e))
(defn get-read-only
[el]
(-> el (aget "readOnly") js/Boolean))
(defn get-type
[el]
(let [type (.-type el)]
(if (some? tpye) type "")))
(defn get-tag
[el]
(.-tagName el))
(defn get-content-editable
[el]
(.-isContentEditable el))
(defn prevent-default
[e]
(if (some? (.-preventDefault e))
(do
(.preventDefault e)
(set! (.-returnValue e) false)
false)
true))
(defn listen!
[el evt-name handler]
(cond
(fn? (.-addEventListener el)) (.addEventListener el evt-name handler)
(fn? (.-attachEvent el)) (.attachEvent el (str "on" evt-name) handler)
:else (aset el (str "on" evt-name) handler)))
pred.cljs
(ns nobsgb.pred)
;;;; 断言
(defonce ^:const KEYCODES
{:backspace 8
:r 82})
(defn matches-key?
"是不是婚配指定键码"
[indicated-key-code key-code]
(= indicated-key-code key-code))
(def ^{:doc "是不是为退格键"}
backspace?
(partial matches-key? (:backspace KEYCODES)))
(def ^{:doc "是不是为字母R键"}
r?
(partial matches-key? (:r KEYCODES)))
(defn with-ctrl?
"是不是在按ctrl的基础上按其他键"
[ctrl-key]
(or (= ctrl-key "1")
(true? ctrl-key)))
(defn ctrl+r?
"是不是为ctrl+r"
[ctrl-key key-code]
(and (with-ctrl? ctrl-key)
(r? key-code)))
(def not-ctrl+r? (complement ctrl+r?))
(defn escapable-type?
"是不是为可跳过的type属性"
[type]
(some?
(some->> type
(re-matches #"(?i)text|password|tel|number|email|search|url"))))
(defn escapable-tag?
"是不是为可跳过的tag"
[tag]
(some?
(some->> tag
(re-matches #"(?i)input|textarea"))))
(def ^{:doc "是不是设置为可编辑元素"}
content-editable? identity)
(def ^{:doc "是不是设置为只读"}
read-only? identity)
(def writable? (complement read-only?))
(defn escapable-backspace?
[key-code read-only type tag content-editable]
(and (backspace? key-code)
(writable? read-only)
(or (escapable-type? type)
(escapable-tag? tag)
(content-editable? content-editable))))
(defn escapable?
[key-code read-only type tag content-editable ctrl-key]
(or
(and (not-ctrl+r? ctrl-key key-code)
(not (backspace? key-code)))
(escapable-backspace? key-code read-only type tag content-editable)))
总结
尊敬原创,转载请说明来自:http://www.cnblogs.com/fsjohn… ^_^肥仔John