uni-app 鸿蒙上架审核不通过需要支持连接键盘时tab键或方向键能切换页面的焦点元素

uni-app 鸿蒙上架审核不通过需要支持连接键盘时tab键或方向键能切换页面的焦点元素

16 回复

响应回车需要监听onkeydown,然后发现是13,就触发相应的逻辑。这可能需要在渲染层监听。 我们已经关注到此事 后续会在内置组件里解决

更多关于uni-app 鸿蒙上架审核不通过需要支持连接键盘时tab键或方向键能切换页面的焦点元素的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


鸿蒙不支持plus吧,之前可以plus.key.addEventListener,现在鸿蒙这边怎么去监听onkeydown呢?

回复 g***@qq.com: 用renderjs在渲染层监听浏览器的事件

你的应用里的现在的表现是什么?我测试了一下 平板模式+键盘,在多个 input 里可以正常切换 tab 和响应回车事件。
<template>
<view>
<view>page index</view>
<view>
input 测试, 键盘输入 123 按下回车应当会弹窗</view>
<input @confirm=“onConrm” style=“border: 1px solid;” />
<view> 第二个 input</view>
<input style="border: 1px solid blue;" />
</view>
</template>

<script> export default { data() { return { } }, methods: { onConrm(e) { console.log('onConfirm', e.detail.value); uni.showToast({ title: e.detail.value }) } } } </script>

键盘焦点应该是优化建议,并不是必须的,如果你因为这一条理由被驳回,可以发起申诉,和审核员沟通。

回复 DCloud_UNI_OttoJi: 现在已经不仅仅是input框这些,页面的功能块,比如用<view @tap=“xxx()”>功能1</view>的功能块也需要支持tap键了。这个应该已经成了审核规范了,因为华为开发者论坛也出现了一些这个问题。

回复 g***@qq.com: 看到你的反馈了。这个问题是新出的,我认为你是可以进一步反馈的,和审核员沟通,这个之前并没有测试过。你也自查你是否错误勾选了 2in1 devicetype

类似这样的功能,他们也会要支持tab键

我的应用也是这个原因被卡了,已经一周了,还没找到适合的解决方法。 华为的《设备兼容性》规范11月18号已经更新了,页面没有 input 也要响应tab键或方向键切换! https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/device-compatible

我看了这个是针对的 平板、电脑、折叠电脑的强制要求,你可在代码中搜索 devicetype 只保留 phone ,在 uniapp 后台或者 agc 后台也确保不勾选上述平台,只勾选 phone 平台

目前我们试下来,可以在提交审核的时候不要勾选平板,只勾选手机,这样是可以过。只勾选手机默认是支持平板的,下面是他们的说明,可以先这样提交审核。

1、支持设备类型包含手机的应用会默认兼容分发到平板或PC设备 2、支持设备类型包含平板的应用会默认兼容分发到PC设备,详请参考官网

下面的例子解决了鸿蒙上的走焦问题。可以通过审核 <template>
<view tabindex="-1" class="test-content">
<view class=“test” tabindex=“0” :class="{ ‘focused’: focusedElement === test-click1 }" id=“test-click1”
@focus=“setFocusedElement(test-click1)” @click=“handleClick”></view>
<view class=“test” tabindex=“0” :class="{ ‘focused’: focusedElement === test-click2 }" id=“test-click2”
@focus=“setFocusedElement(test-click2)” @click=“handleClick”></view>
</view>
</template>

<script> export default { data() { return { focusedElement: '' } }, methods: { setFocusedElement(elementId) { this.focusedElement = elementId; }, handleClick() { this.setFocusedElement('text-click1') }, }, } </script> <script module="test" lang="renderjs"> // RenderJS 模块 - 专门处理键盘事件 export default { mounted() { this.initKeyboardEvents(); }, methods: { // 初始化键盘事件监听 initKeyboardEvents() { console.log('Initializing keyboard events in RenderJS'); // 为整个页面添加键盘事件监听 if (typeof document !== 'undefined' && document.addEventListener) { document.addEventListener('keydown', this.handleKeyDown.bind(this)); console.log('Keyboard event listener added in RenderJS'); } else { console.warn('Document not available for keyboard events'); } }, // 处理键盘事件 handleKeyDown(event) { console.log('Key event in RenderJS:', event.key, event.keyCode); // 获取按键信息 const key = event.key; const keyCode = event.keyCode; // 阻止默认行为 event.preventDefault(); event.stopPropagation(); // 调用逻辑层方法处理键盘导航 this.handleKeyboardNavigation(key, keyCode); }, // 处理键盘导航 handleKeyboardNavigation(key, keyCode) { // 获取所有可聚焦元素 const focusableElements = this.getFocusableElements(); if (focusableElements.length === 0) return; // 获取当前聚焦元素 const currentElement = document.activeElement; let currentIndex = focusableElements.findIndex(el => el === currentElement); // 如果没有当前聚焦元素,默认聚焦第一个 if (currentIndex === -1) { currentIndex = 0; focusableElements[currentIndex].focus(); this.updateFocusState(focusableElements[currentIndex].id); return; } // 根据按键处理导航 switch(key) { case 'ArrowRight': case 'Right': case 'ArrowDown': case 'Down': // 下一个元素 this.focusNextElement(focusableElements, currentIndex); break; case 'ArrowLeft': case 'Left': case 'ArrowUp': case 'Up': // 上一个元素 this.focusPreviousElement(focusableElements, currentIndex); break; case 'Enter': case ' ': // 触发点击事件 this.triggerClick(currentElement); break; case 'Escape': case 'Esc': // 关闭子菜单 this.callOwnerMethod('closeSubMenu'); // 聚焦回主菜单 if (focusableElements.length > 0) { focusableElements[0].focus(); this.updateFocusState(focusableElements[0].id); } break; case 'Tab': // Tab键:下一个元素,Shift+Tab:上一个元素 if (event.shiftKey) { this.focusPreviousElement(focusableElements, currentIndex); } else { this.focusNextElement(focusableElements, currentIndex); } break; default: console.log('Unhandled key:', key); break; } }, // 获取所有可聚焦元素 getFocusableElements() { try { const elements = document.querySelectorAll('[tabindex="0"]'); return Array.from(elements).filter(el => { // 过滤掉隐藏或不可见的元素 const style = window.getComputedStyle(el); return style.display !== 'none' && style.visibility !== 'hidden'; }); } catch (error) { console.error('Error getting focusable elements:', error); return []; } }, // 聚焦下一个元素 focusNextElement(elements, currentIndex) { const nextIndex = (currentIndex + 1) % elements.length; elements[nextIndex].focus(); this.updateFocusState(elements[nextIndex].id); // 确保元素在可视区域内 this.scrollToElement(elements[nextIndex]); }, // 聚焦上一个元素 focusPreviousElement(elements, currentIndex) { const prevIndex = currentIndex > 0 ? currentIndex - 1 : elements.length - 1; elements[prevIndex].focus(); this.updateFocusState(elements[prevIndex].id); // 确保元素在可视区域内 this.scrollToElement(elements[prevIndex]); }, // 触发点击事件 triggerClick(element) { if (element) { console.log('Triggering click on element:', element.id); // 创建并派发鼠标点击事件 const clickEvent = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); element.dispatchEvent(clickEvent); } }, // 更新焦点状态到逻辑层 updateFocusState(elementId) { this.callOwnerMethod('setFocusedElement', elementId); }, // 滚动到元素确保可见 scrollToElement(element) { if (element && element.scrollIntoView) { element.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' }); } }, // 调用逻辑层方法 callOwnerMethod(methodName, ...args) { if (this.$ownerInstance) { this.$ownerInstance.callMethod(methodName, ...args); } } } } </script> <style lang="scss" scoped> .test-content { height: 100vh; .test { width: 100rpx; height: 100rpx; background-color: red; } .focused { // 样式 } } </style>

感谢老哥提供代码,我们试下。

针对鸿蒙审核要求,建议在uni-app项目中实现键盘导航功能:

  1. 在App.vue或页面级组件中监听键盘事件:
onMounted(() => {
    document.addEventListener('keydown', handleKeyDown)
})
  1. 实现焦点切换逻辑:
const handleKeyDown = (e) => {
    const focusableElements = document.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])')
    const currentIndex = Array.from(focusableElements).indexOf(document.activeElement)
    
    if(e.key === 'Tab') {
        e.preventDefault()
        const nextIndex = (currentIndex + 1) % focusableElements.length
        focusableElements[nextIndex].focus()
    }
    
    if(e.key === 'ArrowDown' || e.key === 'ArrowUp') {
        e.preventDefault()
        const direction = e.key === 'ArrowDown' ? 1 : -1
        const nextIndex = (currentIndex + direction + focusableElements.length) % focusableElements.length
        focusableElements[nextIndex].focus()
    }
}
  1. 为可聚焦元素设置合适的tabindex属性:
<button tabindex="0">按钮</button>
<input tabindex="0" />
  1. 使用CSS增强焦点样式:
:focus {
    outline: 2px solid #007AFF;
    outline-offset: 2px;
}
回到顶部