我正在开发一个聊天应用程序,我在iOS的听写功能上遇到了一个奇怪的问题。
场景如下:
- 用户关注输入字段并开始口述一些文本(使用iOS提供的本地听写)
- 现在他们点击发送按钮,这将创建聊天消息,清除输入的文本并再次聚焦输入(使用户能够立即编写下一条消息)。
- 但这一指示似乎并没有停止。当用户再次点击输入字段时,已经发送的文本将重新出现,同时用户在此期间所说的任何内容也将显示。
有没有人知道如何告诉iOS停止听写(最好使用JavaScript,但在Swift的解决方案也会有所帮助)。
谢谢!杰西
最小的例子:
const input = document.getElementById('input');
const button = document.getElementById('button');
button.addEventListener('click', () => {
input.value = '';
input.focus();
})
<input id="input"/>
<button id="button">Send</button>
<ul>
<li>Open this page on iOS</li>
<li>Focus the input and start dication</li>
<li>Click send => input is cleared</li>
<li>Click on the input => text is entered again :(</li>
</ul>
https://codepen.io/jjd/pen/vYZMGBy
我最近遇到了同样的情况,并设法在网络上的一些聊天演示中复制了同样的问题,经过一段时间的挖掘,我发现了旧的答案以及为什么会发生这种情况的解释(以及为什么一些解决方案失败)。
这里的关键是,iOS听写结束时:
- 用户失去焦点
- 用户轻按iOS键盘的
Done
键。
虽然理论上点击你的Send
按钮应该从聊天输入中移除焦点并完成听写,但实际上,从失去输入焦点到恢复输入焦点之间的顺序是如此之快,以至于iOS不会费心完成听写,因为它无论如何都会立即恢复焦点。此外,添加一些延迟来允许iOS键盘完成将最终隐藏键盘,这可能会在你发送消息和手动处理焦点时关闭和打开多次,这是不可取的。
如果你看这里,你可以看到一个主题的快速解释,有一个可能的解决方案,你的问题,我测试了大多数解决方案,他们仍然适用于iOS 14。我的想法是将焦点移到一个元素上,并将焦点移到一个类似的元素上,以避免隐藏键盘,然后手动恢复它,不同之处在于它必须是异步的,以保证iOS的正确响应。我的做法是创建一个虚拟文本输入,并将焦点重定向到该输入:
const dummy = document.createElement('input');
dummy.setAttribute('type', 'text');
dummy.style.position = 'absolute';
dummy.style.opacity = 0;
dummy.style.height = 0;
document.body.append(dummy);
dummy.focus();
然后,设置一个异步超时来重定向到真正的输入元素,清除输入,等等:
setTimeout(() => {
input.value = '';
input.focus();
dummy.remove(); //Notice this
}, 100);
很粗糙,但它完成了工作。我不知道其他网站/应用程序如何处理这种情况,因为我只测试了本地应用程序而不是网站。也许他们干净的代码一开始就没有这个问题?😛