【问题标题】:How to programmatically focus on a textfield on page load for mobile safari?如何以编程方式关注移动 Safari 页面加载的文本字段?
【发布时间】:2018-06-21 18:54:42
【问题描述】:

注意:由于与工作相关的更改,我无法再验证此处发布的答案。很可能,我永远无法接受下面的答案。此处发布的信息对 IMO 很有用,所以我将保持原样。如果您认为自己知道答案,请随时回答,我们会让社区决定哪些有用。


背景

我正在为 iPod Touch 开发一个standalone web app。我的要求之一是在页面加载时关注文本字段,以便用户可以连续执行任务(例如使用条形码阅读器)。

问题

问题在于它确实聚焦有问题的文本字段,但是键盘没有上去。 有解决办法吗?还是 Apple 设计的?

HTML 示例

我不确定如何将其放入代码 sn-p,但这是我一直在尝试的地方:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0.0">

    <meta name="apple-mobile-web-app-capable" content="yes">
    <link rel="apple-touch-icon" href="https://cdn57.androidauthority.net/wp-content/uploads/2016/06/android-win-2-300x162.png">

    <title>TESTING</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

    <script>
        // javascript goes here
    </script>
</head>
<body>

    <section id="content">

        <div class="container" style="margin-top: 50px;" >

            <p>Testing textfield focus</p>

            <form method="POST">
                <div class="row">
                    <div class="col-xs-12">
                        <input type="text" class="form-control first-responder" />
                    </div>
                    <div class="col-xs-12">
                        <button type="submit" class="btn" style="width: 100%" >OK</button>
                    </div>
                </div>
            </form>

        </div>

    </section>

</body>
</html>

我在 Safari 上查看此内容,然后将其添加到主屏幕,使其充当独立的网络应用程序。

尝试

我尝试四处寻找解决方案,第一个(我丢失了链接)建议尝试像这样的超时:

$(function () {
    var firstResponder = $(".first-responder");
    setTimeout(function() {
        firstResponder.focus();

    }, 1000);

})

我发现的另一个solutions 建议像这样设置选择范围:

$(function () {
    var firstResponder = $(".first-responder");
    setTimeout(function() {
        firstResponder[0].setSelectionRange(0, 9999);

    }, 1000);

})

There 还建议将其绑定到如下点击:

$(function () {
    var firstResponder = $(".first-responder");
    firstResponder.on('click', function() {
        firstResponder.focus();
    });

    firstResponder.focus().click();
})

我也尝试过像这样触发 touchstart:

$(function () {
    var firstResponder = $(".first-responder");
    firstResponder.on('touchstart', function() {
        firstResponder.focus();
    });

    firstResponder.trigger('touchstart');
})

我也尝试过像这样的简单 ajax 调用(不要介意成功/错误。我想做的只是在 ajax 调用之后专注):

function doAjax() {
    var firstResponder = $(".first-responder");

    $.ajax({
        url: "#",
        method: "POST",
        dataType: "json",
        success: function(result) {
            firstResponder.focus();
        },
        error: function(request, error) {
            firstResponder.focus();         
        }
    });
}

我有点绝望,所以我也尝试了setting some css:

user-select: text;
-webkit-user-select: text;

这些解决方案适用于 iOS 9.1(css 除外),但所有解决方案在 iOS 11.1.1 上都失败了。我尝试结合各种解决方案、设置超时等,但似乎都没有。正如我所指出的,它确实 focus 因为我可以看到文本字段的边框变为蓝色,表示它具有焦点。但是我也需要显示键盘。

此行为似乎是 bug 或 usability/security feature。如果这是设计使然(即安全功能),Apple 是否有官方文档对此进行了讨论?

附录

如果您认为条码阅读器可能是问题所在,那么事实并非如此。在我正在进行的项目中,条形码阅读器取代了本机键盘。理论上,即使没有条形码,只要我能在页面加载时调出键盘,我应该就能满足我的要求。

连续的任务是可能的,因为条形码阅读器可以在它读取的条形码之后包含一个 Enter 键,从而提交文本字段所在的表单。页面重新加载后,如果文本字段自动聚焦,用户需要做的就是读取另一个条形码。页面再次提交,重新加载,自动对焦,循环可以重复。

【问题讨论】:

  • 您是使用 UIWebView 还是 WKWebView 来加载您的主页。请参考本指南:- developer.apple.com/documentation/uikit/uiwebview
  • 没有。抱歉,iOS 标签可能会产生误导,但我没有使用 Obj-C 或 Xcode 进行编程。相反,我正在开发一个独立的网络应用程序。基本上是 html 和 jQuery。所以不行。不使用UIWebView。
  • 我多么希望刚刚在 iOS 上进行开发,事情可能要简单得多。我还没有尝试过,但我认为如果使用 Obj-C 开发的解决方案是通过 IB 将 UIWebView 的 keyboardDisplayRequiresUserAction 属性设置为 false。但一个人只能做梦......
  • @Keale 你是在真机还是模拟器上测试?
  • @arturdev 在真实设备上。实际上是两个设备。一个在 iOS 9 中,一个在 iOS 11 中。我手头有设备,我只是将 // javascript goes here 的内容替换为此处建议的解决方案以进行检查。

标签: jquery ios mobile-safari


【解决方案1】:

经过一番艰苦的测试,我找到了一种在我女朋友的 iphone 7 和 ios 11 上工作的方法,现在我不知道它是否满足你的需求,但它确实弹出了虚拟键盘!

这是测试html:

<input type='text' id='foo' onclick="this.focus();">
<button id="button">Click here</button>

这是javascript:

function popKeyboard(input) {
  input.focus();
  input.setSelectionRange(0, 0);
}

$("#button").on("click", function() {
  popKeyboard($("#foo"));
});

这是fiddle。

哦,还有CanIUse,以防万一!

现在,当我们单击按钮时,它的计算结果为用户输入,因为只有在用户提供输入时才能弹出键盘(在 android 和 ios 中),我们运行函数 popKeyboard,它聚焦输入并将 selectionRange 设置为 0,0,这意味着它将插入符号设置为 0,并且应该弹出键盘。

这是在 Android 和带有 IOS 11 的 Iphone 7 中测试的。

小心她确实警告过我她的 ios 11 没有完全更新,但如果它有效,请告诉我!

【讨论】:

  • 感谢您的洞察力!我试过这个,不幸的是,它没有用。但是我checked 发现由于某种原因,我的设备不支持setSelectionRange。 (这就是我所说的洞察力)。我将尝试调查为什么设备现在不支持它。非常感谢! :)
【解决方案2】:

你试过了吗?

 $(function(){
    $('input.form-control.first-responder').first().focus();
  });

选择器通过 first() 缩小范围,并确保它不受页面中其他类似类的影响。

【讨论】:

  • 刚刚试过了。适用于 iOS 9 但不适用于 iOS 11。顺便说一句:)
【解决方案3】:

看看这个问题和解决方案: jQuery Set Cursor Position in Text Area

如果您在 ajax ready event 之后使用此解决方案中描述的功能,即使在 iOS 11.2.2 上的 Safari 中也会显示键盘

【讨论】:

  • 我尝试了 2 个答案,以及问题的解决方案,它的行为相同。在 iOS 9 上工作但在 iOS 11 上没有工作。谢谢你的建议顺便说一句:)
【解决方案4】:

使用ajaxComplete 代替load 或ready 事件。

我只是通过 ajax 和 ajaxComplete 方法加载 1 个文件,我已经为输入字段设置了焦点。

这是一个有效的例子,我希望这对你有用。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0.0">

    <meta name="apple-mobile-web-app-capable" content="yes">
    <link rel="apple-touch-icon" href="https://cdn57.androidauthority.net/wp-content/uploads/2016/06/android-win-2-300x162.png">

    <title>TESTING</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
	
	<style>
	span{
		display:none;
	}
	</style>
	
    <script>
	$(document).ready(function(){
	
		$("span").load("https://www.w3schools.com/xml/cd_catalog.xml");
	
		$(document).ajaxComplete(function(){
			$(".first-responder")[0].focus();
		});
	});
    </script>
</head>
<body>

    <section id="content">

        <div class="container" style="margin-top: 50px;" >

            <p>Testing textfield focus</p>

            <form method="POST">
                <div class="row">
                    <div class="col-xs-12">
                        <input type="text" class="form-control first-responder" />
                    </div>
                    <div class="col-xs-12">
                        <button type="submit" class="btn" style="width: 100%" >OK</button>
                    </div>
                </div>
            </form>

        </div>

    </section>
<span></span>
</body>
</html>

【讨论】:

  • 感谢您的努力,真的。 :) 但它不适用于 iOS 11。但它适用于 iOS 9。
【解决方案5】:

如果您需要确保浏览器已完全加载,而不仅仅是onDOMContentReady,请使用标准的load 事件,因为一旦加载完成(即渲染完成)就会触发此事件

由于一些奇怪的是现代 Web 工具包浏览器(chrome、iOS11)由于某种原因添加了延迟,load 事件在浏览器实际完全加载之前触发。但是,我确保仍然使用load 事件作为起点。

(function($){
  $(function(){
      window.addEventListener("load", function(){
        setTimeout(function(){  $(".first-responder").focus();  }, 150);
      });
  })
})(jQuery);

https://jsfiddle.net/barkermn01/xzua65jd/1/

【讨论】:

  • 感谢您的建议。我试过了,但它似乎不起作用?我以为是因为你拼错了function(我更正了)。但似乎仍然不起作用。
  • 修正了错字,这很奇怪似乎需要延迟认为加载只是触发了一点点到早期更新代码现在为您修复它
【解决方案6】:

只是做了一些更多的实验。在 iOS 11 中,如果您尝试在第一个控件上设置 .focus() 而不用户第一次触摸控件,则不会显示键盘。但是,如果您在 .focus() 在另一个元素上之前没有在当前 document.activeElement 上使用 .blur(),则 .focus() 会显示键盘。

下面的代码可以通过 iPod 的按键(条形码阅读器、扫描板)为我工作:-

$(window).keypress(function (e) {
    if (e.which === 13) {
        switch (true) {
            case window.location.href.indexOf('FindReplenishmentLocation') > -1:
            case window.location.href.indexOf('ConfirmReplenishmentLocation') > -1:
            case window.location.href.indexOf('ConfirmReplenishmentPickFace') > -1:
                if (document.activeElement.id === 'pickFaceLocationTextBox' || document.activeElement.id === 'bulkLocationTextBox') {
                    if ($('#skuTextBox').val()) {
                        $('#skuTextBox').focus().select();
                    }
                    else {
                        if (isMobile) {
                            $('#skuTextBox').focus().select();
                        }
                        else {
                            $('#skuTextBox').focus();
                        }
                    }
                }
                else {
                    if (window.location.href.indexOf('ConfirmReplenishmentPickFace') > -1) {
                        if ($('#qtyPutAwayNumericTextBox').val()) {
                            $('#qtyPutAwayNumericTextBox').focus().select();
                        }
                        else {
                            if (isMobile) {
                                $('#qtyPutAwayNumericTextBox').focus().select();
                            }
                            else {
                                $('#qtyPutAwayNumericTextBox').focus();
                            }
                        }
                    }
                    else {
                        $('#next-btn').trigger('click');
                    }
                }
                break;                
            default:
                break;
        }

        e.preventDefault();
    }
});

【讨论】:

    【解决方案7】:

    首先在 webview 上使用 becomeFirstResponder()

    【讨论】:

      猜你喜欢
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2011-07-24
      相关资源
      最近更新 更多