【JS】js下监听(非input等可获取焦点)元素的键盘按下事件(vue通用)

本文介绍了在Vue中如何对不可获取焦点的元素监听键盘事件,包括全局监听按键、使用tabindex和contenteditable属性。通过设置tabindex,元素可以被聚焦并参与键盘导航,而contenteditable属性使元素可编辑并获取焦点。这些方法适用于需要在特定交互场景下监听键盘事件的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大部分键盘按下事件的监听是可获取焦点元素(input,button,textarea)可以生效,而当我们需要对不可获取焦点元素进行监听操作呢,本篇介绍一下不可获取焦点元素监听键盘按下的方法。

三种方式(以下介绍方法vue通用)

  • 全局监听按键按下事件
  • 使用tabindex
  • 使用contenteditable

本文案例功能:

  1. 当点击open时,open变为close,class改变
  2. 当点击close或者按下键盘按键ESC时,close变为open,class改变

HTML

<div id="test1" class="open">open</div>

JS

var isKeyClose = false // 全局变量当前状态
// 切换的执行操作
function check(){
// 点击改变状态
 isKeyClose = !isKeyClose
 // 根据状态改变值
 if(isKeyClose){
   test1.className = 'close'
   test1.innerHTML = 'close'
 }else{
   test1.className = 'open'
   test1.innerHTML = 'open'
 }
}

一、 全局监听按键按下事件

document.onkeydown = function(e) {
	var keyCode = e.keyCode || e.which || e.charCode
	if(e.keyCode === 27 && isKeyClose){
	 check(); // 切换执行方式 
	}
}

二、使用tabindex

引用:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/tabindex

全局属性 指示其元素是否可以聚焦,以及它是否/在何处参与顺序键盘导航(通常使用Tab键,因此得名)。

  • tabindex=负值 (通常是tabindex=“-1”),表示元素是可聚焦的,但是不能通过键盘导航来访问到该元素,用JS做页面小组件内部键盘导航的时候非常有用。
  • tabindex=“0” ,表示元素是可聚焦的,并且可以通过键盘导航来聚焦到该元素,它的相对顺序是当前处于的DOM结构来决定的。
  • tabindex=正值,表示元素是可聚焦的,并且可以通过键盘导航来访问到该元素;它的相对顺序按照tabindex 的数值递增而滞后获焦。如果多个元素拥有相同的 tabindex,它们的相对顺序按照他们在当前DOM中的先后顺序决定

总结就是:tabindex属性可以有获取焦点的功能,当设置为‘-1’时,不会因为使用键盘tab键影响

因此,我们可以使用tabindex让div元素获取焦点

<div id="test1" tabindex='-1' class="open">open</div>
test1.addEventListener('keydown',function(e) {
	// esc的code是27,并且当前isKeyClose是true时
	if(e.keyCode === 27 && isKeyClose){
	  check()
	}
})

三、使用contenteditable

引用:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/contenteditable

全局属性 contenteditable 是一个枚举属性,表示元素是否可被用户编辑。 如果可以,浏览器会修改元素的部件以允许编辑。

该属性必须是下面的值之一:

  • true 或空字符串,表示元素是可编辑的;
  • false 表示元素不是可编辑的。

总结就是:contenteditable属性设置之后可以使元素可编辑,当可编辑时也是获取焦点的

<div id="test1" contenteditable='true' class="open">open</div>

说明:

  1. tabindex和contenteditable:使用时都需要先对元素进行点击来获取焦点,再进行按键,
    可适用操作同一个元素的,例如:全屏和退出全屏,且全屏与退出全屏绑定的是同一个元素;
    对于不用点击就监听按键的不适用;
  2. contenteditable:使用时会有编辑功能,当该元素不需要编辑时使用,会影响功能
<think>好的,我现在需要解决用户在UniApp中遇到的键盘弹起问题,比如H5下TabBar遮挡输入框的情况。首先,用户提到的adjust-position属性无效,这可能是因为在不同平台或环境下该属性的表现不一致。我需要回忆一下之前处理类似问题的经验,以及参考提供的引用资料。 根据引用[1],当adjust-position无效时,可以尝试手动调整布局。比如,监听键盘弹起事件获取键盘高度,然后动态调整输入框的位置或页面的padding-bottom。引用[4]提到的方法是通过获取键盘高度,然后设置按钮的fixed定位和bottom值,这可能同样适用于调整输入框的位置。 接下来,我需要考虑不同平台的兼容性,比如iOS和安卓。引用[2]指出iOS键盘高度可能变化,需要用通知来监听键盘事件,并动态调整布局。在UniApp中,可能需要使用uni.onKeyboardHeightChange来实时获取键盘高度,而不是固定的值。 另外,引用[3]提到摇树优化可能导致动画失效,虽然这里的问题不是动画,但需要注意打包配置是否影响了相关功能的正常运作,比如某些事件监听是否被错误地优化掉。 用户的需求是实现键盘弹起时的布局调整,可能需要综合使用动态样式绑定、监听键盘事件、调整布局结构等方法。例如,当键盘弹起时,计算键盘高度,将输入框上移或增加页面底部的内边距,避免遮挡。同时,可能需要在输入框获得焦点时触发这些调整,并在失去焦点时恢复原样。 此外,可能需要处理输入框的位置在页面中间的情况,这时简单的底部调整可能不够,需要更精确的计算,比如使用scrollIntoView方法将输入框滚动到可视区域。或者,使用CSS的transform来平移输入框的位置。 最后,还需要测试不同平台下的表现,确保解决方案的通用性。例如,在H5中使用window.addEventListener来监听resize事件,或使用UniApp提供的API来统一处理。同时,考虑软键盘弹出时可能引起的页面高度变化,动态调整布局元素的位置。</think>在UniApp中处理键盘弹起问题需结合平台特性和动态布局调整,以下是具体实现方法: ### 一、基础处理方法 1. **开启原生属性适配** ```vue <template> <input adjust-position="true" /> </template> ``` - 添加`adjust-position`属性可让页面自动上推(安卓/iOS部分版本有效),但H5可能存在失效问题[^1] 2. **动态布局调整(通用方案)** ```javascript export default { data() { return { keyboardHeight: 0 } }, onReady() { uni.onKeyboardHeightChange(res => { this.keyboardHeight = res.height this.adjustLayout() }) }, methods: { adjustLayout() { // 示例:底部按钮定位 const buttonStyle = { position: 'fixed', bottom: `${this.keyboardHeight + 10}px` } // 或调整页面内边距 uni.pageScrollTo({ scrollTop: document.documentElement.scrollHeight, duration: 300 }) } } } ``` ### 二、进阶处理方案 #### 场景1:TabBar遮挡输入框 ```css /* 动态修改页面底部间距 */ .page-container { padding-bottom: calc(env(safe-area-inset-bottom) + v-bind('keyboardHeight + "px"')); transition: padding-bottom 0.3s; } ``` #### 场景2:输入框居中定位 ```javascript // 输入获取焦点时 focusHandler() { this.$nextTick(() => { const query = uni.createSelectorQuery().in(this) query.select('.input-box').boundingClientRect(res => { if (res.top < this.keyboardHeight) { window.scrollTo({ top: window.scrollY + res.top - 100, behavior: 'smooth' }) } }).exec() }) } ``` ### 三、平台特性处理 1. **iOS注意事项** ```javascript // 处理第三方输入法高度波动 let maxHeight = 0 uni.onKeyboardHeightChange(res => { if (res.height > maxHeight) { maxHeight = res.height } this.keyboardHeight = maxHeight }) ``` 2. **安卓兼容方案** ```javascript // 监听窗口尺寸变化 window.addEventListener('resize', () => { const visualViewport = window.visualViewport this.keyboardHeight = window.innerHeight - visualViewport.height }) ``` ### 四、优化建议 1. 使用`uni.hideKeyboard()`主动控制键盘关闭 2. 添加防抖处理高频触发事件 3. 配合`scroll-view`实现精准滚动定位 4. 使用CSS环境变量处理安全区域: ```css .keyboard-space { height: calc(v-bind('keyboardHeight') * 1px + env(safe-area-inset-bottom)); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值