摘要:而以后的浏览器则屏蔽了和的上述行为,而是采用实现回退和实现前进。附加功能现在我们的目的是页面不会因为用户误操作而刷新,导致页面数据丢失。这里有两个组合键同样会的导致页面刷新刷新当前页面,可被阻止关闭当前窗体或标签页,无法阻止。
前言
前几天用户反映在录入资料时一不小心错按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
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/83153.html
摘要:前言对于问题多多的,浏览器样式闪烁是一个不可忽视的话题,但对于的浏览器就不用理会了吗下面尝试较全面地解密。示例说明,不管在哪里引入,在页面的所有下载完成前,整个页面将不会被渲染。 前言 对于问题多多的IE678,FOUC(flash of unstyled content)——浏览器样式闪烁是一个不可忽视的话题,但对于ever green的浏览器就不用理会了吗?下面尝试较全面地解密F...
摘要:前言对于问题多多的,浏览器样式闪烁是一个不可忽视的话题,但对于的浏览器就不用理会了吗下面尝试较全面地解密。示例说明,不管在哪里引入,在页面的所有下载完成前,整个页面将不会被渲染。 前言 对于问题多多的IE678,FOUC(flash of unstyled content)——浏览器样式闪烁是一个不可忽视的话题,但对于ever green的浏览器就不用理会了吗?下面尝试较全面地解密F...
摘要:前言对于问题多多的,浏览器样式闪烁是一个不可忽视的话题,但对于的浏览器就不用理会了吗下面尝试较全面地解密。示例说明,不管在哪里引入,在页面的所有下载完成前,整个页面将不会被渲染。 前言 对于问题多多的IE678,FOUC(flash of unstyled content)——浏览器样式闪烁是一个不可忽视的话题,但对于ever green的浏览器就不用理会了吗?下面尝试较全面地解密F...
摘要:我打算分成前端魔法堂异常不仅仅是和前端魔法堂调用栈,异常实例中的宝藏两篇分别叙述内置自定义异常类,捕获运行时异常语法异常网络请求异常事件,什么是调用栈和如何获取调用栈的相关信息。 前言 编程时我们往往拿到的是业务流程正确的业务说明文档或规范,但实际开发中却布满荆棘和例外情况,而这些例外中包含业务用例的例外,也包含技术上的例外。对于业务用例的例外我们别无它法,必须要求实施人员与用户共同...
摘要:坑无视和是十分特殊的事件,要求事件处理函数内部不能阻塞当前线程,而却恰恰就会阻塞当前线程,因此规范中以明确在和中直接无视这几个方法的调用。 前言 最近实施的同事报障,说用户审批流程后直接关闭浏览器,操作十余次后系统就报用户会话数超过上限,咨询4A同事后得知登陆后需要显式调用登出API才能清理4A端,否则必然会超出会话上限。 即使在页面上增添一个登出按钮也无法保证用户不会直接关掉浏览器...
阅读 1266·2023-04-26 00:10
阅读 2407·2021-09-22 15:38
阅读 3681·2021-09-22 15:13
阅读 3453·2019-08-30 13:11
阅读 625·2019-08-30 11:01
阅读 2988·2019-08-29 14:20
阅读 3179·2019-08-29 13:27
阅读 1669·2019-08-29 11:33