我使用AngularJS 1.4.7
我有可编辑的输入。如果我们专注于输入并在此输入字段之外单击后,脚本将在"save()"
中执行功能ng-blur
。一切正常,但iPhone 5/6
和iPad
不起作用(不执行ng-blur
中的任何内容)。我不知道为什么,但我推断出问题出在focus/touch
行动中。有人知道问题出在哪里了?
答案 0 :(得分:6)
<强>目标强>
在我的应用中,我们希望在点击时隐藏打开的菜单或搜索结果 菜单或搜索框。
<强>问题强>
单击远离当前元素时,iOS Safari无法正常模糊。
注意强>
您不需要特殊指令。问题不在于ng-blur,它工作正常。问题是,由于Apple在iOS上的不寻常设计,无论您是使用ng-blur还是原生DOM模糊事件,都不会发生模糊事件。
问题原因
Apple设计的移动Safari可以不同于桌面浏览器执行事件冒泡。根据官方Apple文档,如果单击的元素没有附加单击侦听器,则不会触发任何单击事件。如果没有单击事件,焦点不会更改并且不会发生模糊事件,因此即使用户确实单击了页面上的其他位置,当前元素也不会失去焦点。
只有当用户点击带有点击事件监听器的元素时,才会出现模糊。一些元素,如超链接和输入有&#34;内置&#34;用于单击的事件侦听器,因此将始终注册单击,从而导致模糊工作。
通常在桌面浏览器中,无论是否在元素的DOM层次结构中存在已注册的侦听器,都会盲目触发click事件。这就是为什么ng-blur在桌面浏览器中按预期工作,即使在空白空间&#34;。
Apple表示,对于iOS Safari,只有在找到注册的元素才能收听该事件时,他们才会调度该事件。 Apple的文档听起来像是在寻找已注册的事件监听器并在目标元素上处理,但事实并非如此。我在下面的文章中找到了答案,更重要的是,它给出了一个评论。Quirksmode Article on iOS event delegation
首先,如果目标元素没有click事件监听器和处理程序,请注意在文档或正文上放置一个侦听器 not 会导致在iOS Safari上调度click事件。它适用于大多数浏览器,但不适用于iOS。
在发送点击事件之前,Apple似乎正在检查DOM层次结构最多 <body>
标记,但是不检查{{1}标签或以上。因此,您需要一个附加到<body>
下面某个元素的点击事件监听器。
<强>解决方案/解决方法强>
解决方案非常简单。您需要做的就是将所有页面内容包装在&#34; master&#34;容器元素正好在<body>
元素下面,并将侦听器放在那里而不是在主体或文档上。它甚至可以是一个空的处理函数。 Apple仅检查是否已注册。包装所有内容的原因是,无论用户点击的页面在哪里,起泡过程最终都会到达主容器。
如果你这样做,那么ng-blur将在iOS中按预期工作,因为空白空间(没有点击事件监听器的元素)上的click事件将在找到父容器时通过iOS检查。 click事件监听器和click事件将被正常调度,就像在任何其他浏览器中一样。
<强>注意强>
此解决方案有效地使iOS Safari在每个DOM元素的层次结构上看到一个click事件侦听器,诱使它在每个元素上调度click事件,就像普通的浏览器一样。我不知道Apple是否有性能原因他们在iOS中避免这种情况,或者它只是美学/开发者类型偏好(参见示例)。您将使用此变通方法更改应用中的默认iOS行为。
例如,iOS用户可能会意外地在您的网页上选择他们并不意味着的文字,如果没有点击并按住手势,这通常不会发生。
答案 1 :(得分:0)
我不知道为什么会出现这个问题。 但做一件事。制作一个小指令&#39; fake-blur&#39; 。然后在该指令中调用您的方法
App.directive('fakeBlur', function(){
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.blur(function(){
// call you function ex:
scope.save();
})
}
}
});
&#13;
<input type="text" fake-blur/>
&#13;