Mobile Safari:inputfield上的Javascript focus()方法只适用于点击?

时间:2012-08-30 20:00:40

标签: javascript jquery iphone input focus

我似乎无法找到解决此问题的方法。

我有一个像这样的简单输入字段。

<div class="search">
   <input type="text" value="y u no work"/>
</div>​

我正在尝试focus()一个函数内部。 所以在随机函数内部(无论它是什么函数)我都有这条线......

$('.search').find('input').focus();

这适用于每个桌面。

但它在我的iPhone上不起作用。该字段没有聚焦,键盘没有显示在我的iPhone上。

出于测试目的并向我们展示问题,我做了一个快速的样本:

$('#some-test-element').click(function() {
  $('.search').find('input').focus(); // works well on my iPhone - Keyboard slides in
});

setTimeout(function() {
  //alert('test'); //works
  $('.search').find('input').focus(); // doesn't work on my iPhone - works on Desktop
}, 5000);​

知道为什么focus()无法使用iPhone上的超时功能。

要查看实时示例,请在iPhone上测试此小提琴。 http://jsfiddle.net/Hc4sT/

更新

我创建了与我目前在当前项目中面临的完全相同的案例。

我有一个选择框应该 - 当“改变”时 - 将焦点设置到输入字段并滑入iphone或其他移动设备上的kexboard。我发现focus()设置正确但键盘没有出现。我需要键盘出现。

我在这里上传了测试文件http://cl.ly/1d210x1W3Y3W ...如果你在iphone上测试它,你可以看到键盘没有滑入。

9 个答案:

答案 0 :(得分:69)

实际上,伙计们,还有一种方法。我努力想象http://forstartersapp.com(在iPhone或iPad上试试)。

基本上,触摸屏设备上的Safari在focus()文本框方面很吝啬。如果执行click().focus(),即使某些桌面浏览器也会做得更好。但触摸屏设备上Safari的设计人员在键盘不断出现时意识到这对用户来说很烦人,所以他们只关注以下情况:

1)用户点击了某处,并在执行click事件时调用了focus()。如果您正在进行AJAX调用,那么必须同步执行它,例如jQuery中已弃用(但仍然可用)的$.ajax({async:false})选项。

2)此外 - 这个让我忙碌了一段时间 - focus()如果其他一些文本框在当时聚焦的话,似乎仍然无效。我有一个执行AJAX的“Go”按钮,所以我尝试在Go按钮的touchstart事件上模糊文本框,但这只是让键盘消失并在我有机会完成之前移动了视口单击Go按钮。最后,我尝试在Go按钮的touchend事件上模糊文本框,这就像一个魅力!

当您将#1和#2放在一起时,您会获得一个神奇的结果,通过将焦点放在您的密码字段中,使您的登录表单与所有蹩脚的Web登录表单区别开来,让他们感觉更加原生。请享用! :)

答案 1 :(得分:5)

我最近遇到了同样的问题。我找到了一个显然适用于所有设备的解决方案。您无法以编程方式执行异步焦点,但是当其他一些输入已经聚焦时,您可以焦点切换到目标输入。所以你需要做的是创建,隐藏,附加到DOM&amp;在触发事件上关注输入,并在异步操作完成时,再次在目标输入上调用焦点。这是一个示例代码段 - 在您的手机上运行。

编辑:

这里是fiddle with the same code。显然,您无法在手机上运行附加的代码段(或者我做错了什么)。

&#13;
&#13;
var $triggerCheckbox = $("#trigger-checkbox");
var $targetInput = $("#target-input");

// Create fake & invisible input
var $fakeInput = $("<input type='text' />")
  .css({
    position: "absolute",
    width: $targetInput.outerWidth(), // zoom properly (iOS)
    height: 0, // hide cursor (font-size: 0 will zoom to quarks level) (iOS)
    opacity: 0, // make input transparent :]
  });

var delay = 2000; // That's crazy long, but good as an example

$triggerCheckbox.on("change", function(event) {
  // Disable input when unchecking trigger checkbox (presentational purpose)
  if (!event.target.checked) {
    return $targetInput
      .attr("disabled", true)
      .attr("placeholder", "I'm disabled");
  }

  // Prepend to target input container and focus fake input
  $fakeInput.prependTo("#container").focus();

  // Update placeholder (presentational purpose)
  $targetInput.attr("placeholder", "Wait for it...");

  // setTimeout, fetch or any async action will work
  setTimeout(function() {

    // Shift focus to target input
    $targetInput
      .attr("disabled", false)
      .attr("placeholder", "I'm alive!")
      .focus();

    // Remove fake input - no need to keep it in DOM
    $fakeInput.remove();
  }, delay);
});
&#13;
label {
  display: block;
  margin-top: 20px;
}

input {
  box-sizing: border-box;
  font-size: inherit;
}

#container {
  position: relative;
}

#target-input {
  width: 250px;
  padding: 10px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="container">
  <input type="text" id="target-input" placeholder="I'm disabled" />

  <label>
    <input type="checkbox" id="trigger-checkbox" />
    focus with setTimetout
   </label>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:2)

我设法使用以下代码:

event.preventDefault();
timeout(function () {
    $inputToFocus.focus();
}, 500);

我正在使用AngularJS,因此我创建了一个解决了我的问题的指令:

<强>指令:

angular.module('directivesModule').directive('focusOnClear', [
    '$timeout',
    function (timeout) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var id = attrs.focusOnClear;
                var $inputSearchElement = $(element).parent().find('#' + id);
                element.on('click', function (event) {
                    event.preventDefault();
                    timeout(function () {
                        $inputSearchElement.focus();
                    }, 500);
                });
            }
        };
    }
]);

如何使用该指令:

<div>
    <input type="search" id="search">
    <i class="icon-clear" ng-click="clearSearchTerm()" focus-on-clear="search"></i>
</div>

看起来你正在使用jQuery,所以我不知道该指令是否有任何帮助。

答案 3 :(得分:2)

我有一个带有图标的搜索表单,可以在单击时清除文本。但是,问题(在移动设备和平板电脑上)是键盘会折叠/隐藏,因为已移除click事件focus input

text search input with close icon

目标:清除搜索表单后(点击/点击x-icon)保持键盘可见

要完成此操作,请对事件应用stopPropagation(),如下所示:

function clear ($event) {
    $event.preventDefault();
    $event.stopPropagation();
    self.query = '';
    $timeout(function () {
        document.getElementById('sidebar-search').focus();
    }, 1);
}

HTML表单:

<form ng-controller="SearchController as search"
    ng-submit="search.submit($event)">
        <input type="search" id="sidebar-search" 
            ng-model="search.query">
                <span class="glyphicon glyphicon-remove-circle"
                    ng-click="search.clear($event)">
                </span>
</form>

答案 4 :(得分:2)

WunderBart答案的原生javascript实现。

禁用自动缩放using font size

Traceback (most recent call last):
  File "C:/Users/francois.CIRCUS/PycharmProjects/DeadlineMiniMonitor/mini_uimw.py", line 455, in change_value
    self.kill_deadlineslave()
  File "C:/Users/francois.CIRCUS/PycharmProjects/DeadlineMiniMonitor/mini_uimw.py", line 538, in kill_deadlineslave
    CallDeadlineCommand([" RemoteControl ", str(computer_name()), " ForceStopSlave"])
  File "C:/Users/francois.CIRCUS/PycharmProjects/DeadlineMiniMonitor/mini_uimw.py", line 680, in CallDeadlineCommand
    startupinfo=startupinfo, creationflags=creationflags)
  File "C:\Python27\Lib\subprocess.py", line 394, in __init__
    errread, errwrite)
  File "C:\Python27\Lib\subprocess.py", line 644, in _execute_child
    startupinfo)
WindowsError: [Error 5] Access is denied

答案 5 :(得分:1)

<强>更新

我也试过这个,但无济于事:

$(document).ready(function() {
$('body :not(.wr-dropdown)').bind("click", function(e) {
    $('.test').focus();
})
$('.wr-dropdown').on('change', function(e) {
    if ($(".wr-dropdow option[value='/search']")) {
        setTimeout(function(e) {
            $('body :not(.wr-dropdown)').trigger("click");
        },3000)         
    } 
}); 

});

我很困惑为什么你说这不起作用,因为你的JSFiddle工作得很好,但无论如何这里是我的建议......

在点击事件的SetTimeOut函数中尝试以下代码行:

document.myInput.focus();

myInput与输入标记的name属性相关联。

<input name="myInput">

并使用此代码模糊字段:

document.activeElement.blur();

答案 6 :(得分:1)

此解决方案效果很好,我在手机上测试过:

document.body.ontouchend = function() { document.querySelector('[name="name"]').focus(); };

享受

答案 7 :(得分:0)

尝试一下:

input.focus();
input.scrollIntoView()

答案 8 :(得分:-3)

请尝试使用on-tap而不是ng-click事件。我有这个问题。我通过在搜索表单标签中创建清晰搜索框按钮并通过点击取代按钮单击清除按钮来解决它。现在工作正常。