場景是這樣:
我要做一個帶輸入框的頁面,然后頁面第一次進來是會彈出一個模態(tài)框,如下:
需求是這樣子的:
點擊模態(tài)框中的“輸入香煙名稱”收起模態(tài)框,直到模態(tài)框完全收起后,觸發(fā)頂部輸入框的focus事件,讓這個input獲得焦點彈起軟鍵盤。
按常理也不難是吧:
$.fn.extend({
animateCss: function (animationName, callback) {
var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
this.addClass('animated ' + animationName).one(animationEnd, function() {
callback && callback.call(this);
$(this).removeClass('animated ' + animationName);
});
}
});
$("#modal").animateCss("bounceOutUp", function(){
$("#input").focus();
});
很簡單的一段代碼,在微信的模擬器上面還是沒有問題,的確是起效,獲得焦點的。但是真機上面測試就gg了,沒有效果。
然后我是寫了個button事件測試研究一下:
<button id="test">test</button>
$("#button").on('touchstart', function() {
$("#input").focus();
});
然后注冊測試用例運行的結(jié)果是:在模擬器上面起效,在真機上面也起效。
最后想想是不是ios的奇特機制,然后用了安卓的機子測試,然后果不其然,安卓的機子是起效的,然后google了一下:
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.
翻譯:我和我的同事發(fā)現(xiàn),iOS將只允許在其他元素上綁定函數(shù)來觸發(fā)focus事件,如果第一個函數(shù)調(diào)用棧是由非編程觸發(fā)的事件(這句不知道怎么翻譯)。在你的案例中,調(diào)用setTimeout開始一個新的調(diào)用堆棧,IOS的安全機制開始阻止你觸發(fā)input元素的focus事件
果斷試了一下,將代碼改成:
$("#modal").animateCss("fadeOut");
$("#input").focus();
是的,確實是這樣是,代碼改成這樣后無論是模擬器上移動端上(ios和安卓)都是可以讓input獲得焦點的。
結(jié)論
ios上只有用戶交互觸發(fā)的focus事件才會起效,而延時回調(diào)的focus是不會觸發(fā)的,說得大佬粗點,你想在ios上focus事件起效就不能講focus時間放在延時里面調(diào)用