Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 373|回复: 0

【移动端debug-4】iOS下setTimeout无法触发focus事件的解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-5-22 13:47:27 | 显示全部楼层 |阅读模式

    开篇总结:其实目前无法解决这个bug。

    这两天做项目遇到了这个case,项目需求是打开页面的时候,input元素自动弹起键盘。由于各种方面的考虑,我们希望通过setTimeout延时200毫秒让input元素focus,demo代码如下:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>IOS下setTimeout无法触发focus事件的解决方案</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
    </head>
    <body>
    <div id="container">
        <input id="input-box" type="text" placeholder="click here to focus.">
    </div>
    <script>
        var container = document.getElementById("container");
        var input = document.getElementById("input-box");
        setTimeout(function () {
            input.focus();
        },200);
    </script>
    </body>
    </html>

     

    • 问题出在哪?

    上面的代码在pc上显示没有问题,但是在安卓上也ok,但是在ios上出了问题,input没有获得焦点,问题出在哪了?

    我通过debug发现,代码能执行到setTimeout里面,并且input元素也没有选择失败,那我们判断是input.focus()这句失效了。

     

    • 前人指路

    然后我们在stackoverflow上搜到了相关的case:Mobile Safari Autofocus text field

    在最高票答案中,来自FastClick团队的大牛指出了IOS下input的获取焦点存在这样的问题:

    my colleagues and I found that iOS will only allow focus to be triggered on other elements, from within a function, if the first function in the call stack was triggered by a non-programmatic event. In your case, the call to setTimeout starts a new call stack, and the security mechanism kicks in to prevent you from setting focus on the input.

    翻译:我和我的同事发现,iOS将只允许在其他元素上绑定函数来触发focus事件,如果第一个函数调用栈是由非编程触发的事件(这句不知道怎么翻译)。在你的案例中,调用setTimeout开始一个新的调用堆栈,IOS的安全机制开始阻止你触发input元素的focus事件。

    github上也有相关的issue:iOS does not show keyboard on .focus()

    里面也有人指出:

    iOS won't, as far as I can tell from testing, show the keyboard without some kind of user interaction.Trying a setTimeout to load it doesnt work. But setting the focus on another element's onClick event brings it up.

    翻译:据我目前测试所知,如果没有通过某种用户交互,iOS不会(触发focus事件)。用setTimeout试图触发focus不工作(setTimeout是延时触发,非用户交互的当下触发focus),但设置另一个元素的onClick事件,就能把focus事件带起来。

        //通过在input以外的其他元素绑定事件可以触发input元素的focus事件
        container.addEventListener("click",function(e){
            input.focus();
        });

     

    • 解决方案?

    目前看来没有更好的办法能在iOS下,通过setTimeout调起focus事件,所以只能把setTimeout去掉,从产品设计上避免。

    如果你有什么好的解决方案,欢迎留言哦!

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-19 12:29 , Processed in 0.062928 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表