做 Layui iframe 里的键盘事件监听,说难不难,说简单也容易翻车 最核心的一点:子页自己的键盘绑定,必须由子页自己在 DOM 加载完成后挂上,父页没法直接插到手。同域下还能调调 parent 函数,跨域就只能靠 postMessage 传信。这几个点,哪个没到位,快捷键就“写是写了,但就是
最核心的一点:子页自己的键盘绑定,必须由子页自己在 DOM 加载完成后挂上,父页没法直接插到手。同域下还能调调 parent 函数,跨域就只能靠 postMessage 传信。这几个点,哪个没到位,快捷键就“写是写了,但就是不响”。
子页的 js 脚本跑起来的时候,document 可能还没完全就绪。这时候急急忙忙写 $(document).on('keydown', ...),等于把事件绑在空气上——尤其是 iframe 刚开始加载,ready 或 DOMContentLoaded 没触发之前,绑了也是白绑。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
常见的报错现象:回车没反应、event.key 取不到值、e.preventDefault() 失效。
$(function(){ ... }) 或 document.addEventListener('DOMContentLoaded', ...) 把监听逻辑包起来document.onkeydown = ...,Layui iframe 的加载顺序不是你能控制的parent 对象不能跨 iframe 监听子页的 keydown,这不是谁故意刁难,是浏览器安全策略的规定,哪怕同域也不行。试过在父页写 iframe.contentWindow.addEventListener('keydown', ...) 的,要么报错,要么静默失败。
唯一的正确路径:子页自己监听,然后通过约定好的方式告诉父页。
parent.layer.close(index) 或 parent.callbackFn(...)(前提是父页已经把函数定义好了)window.parent.postMessage(...),父页那边要严格校验 e.origin,别什么消息都收window.opener 的主意——Layui iframe 不是新窗口,window.opener 永远为 null子页里监听 Enter 确认、Esc 取消,本质上就是模拟点击父页的“确定”和“取消”按钮。但不要硬编码 selector——按钮 class 可能随 layui 版本变化(比如 .layui-layer-btn0 在某些主题下会被覆盖)。
更稳定的做法是:子页通过 parent 调用父页已经暴露的函数,由父页统一处理关闭逻辑。
window.confirmFromIframe = function() { layer.close(layer.getFrameIndex(window.name)); };if (e.key === 'Enter' && parent.confirmFromIframe) parent.confirmFromIframe();if (parent && parent.confirmFromIframe) 的判断,防止子页先于父页执行e.key === 'Escape' 比 e.keyCode === 27 更可靠,后者在部分移动端已经罢工了一个看起来简单的 keydown,在 iframe 场景下埋了好几个隐性断点:输入法状态、focus 丢失、滚动条遮挡,还有 layui 自身对某些按键的拦截(比如分页框里的 Enter)。
最容易踩的坑反而不是逻辑写错,而是时机和上下文错位。
document 的 activeElement 是这个 input,此时按 Enter 默认会触发表单提交——必须在 input 上单独监听并 e.preventDefault()contenteditable 或富文本编辑器,Enter 行为被编辑器接管,document 级监听根本收不到原始事件keydown 可能延迟触发或者丢一次,建议加个防抖(setTimeout 延迟 10ms 再执行)e.key 不支持,必须 fallback 到 e.keyCode,但注意 keyCode 已被标准弃用,仅作兼容用说到底,子页键盘操作的可靠性不取决于监听代码写得多短,而在于它是否跑在正确的上下文里——DOM 就绪了没?focus 在哪?父页函数挂载好了没?这些点任何一个漏掉,快捷键就变成“看起来写了,但就是不响”。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述