Angular.js 移动浏览器应用程序在 iOS 8 Safari 上冻结

Posted

技术标签:

【中文标题】Angular.js 移动浏览器应用程序在 iOS 8 Safari 上冻结【英文标题】:Angular.js mobile browser app freezes on iOS 8 Safari 【发布时间】:2015-05-01 20:57:20 【问题描述】:

我们的 Angular.js Web 应用有时会在 ios8 Safari 上冻结。发生此问题时,不会触发 ng-click 回调。如果您将 ng-click 替换为常规的 javascript onclick,它会起作用。在 iOS8 设备上的 Chrome 中不会发生这种情况。

有其他人在 iOS8 Safari 上注意到这个问题或有解决办法吗?

这个简单的视图有时会在 iOS8 safari 上冻结。当您打开选项卡、转到浏览器上的其他选项卡或离开浏览器体验并稍后返回时,通常会发生冻结。在此示例中,当点击链接时视图冻结时,tapCount 不会增加。视图越复杂,就越容易冻结。在此示例中,当我快速点击链接时,浏览器会冻结几秒钟。通常冻结在真正复杂的视图上需要更长的时间。

var app = angular.module('myApp', []);
app.controller('freezeCtrl', function($scope) 
  $scope['tapCount'] = 0;

$scope['dummyItems'] = [];
for(var i = 0; i < 15; i++) 
    var anItem = 'id': i;
    ($scope['dummyItems']).push(anItem);


$scope['updateTapCount'] = function() 
    $scope.tapCount += 1;
;
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<div  ng-app="myApp">
  <div ng-controller="freezeCtrl">
    <p>Tap Count = tapCount</p>
    <ul>
        <li ng-repeat="item in dummyItems" bindonce>
            <p>This is a dummy item #item.id</p>
        </li>
    </ul>
    <div>
      <button ng-click="updateTapCount()">Button 1</button>
      <button ng-click="updateTapCount()">Button 2</button>
    </div>
  </div>
</div>

【问题讨论】:

如果你看到这种行为,你能发布一个最简单的应用程序的例子吗? 嗨 xpereta,我添加了一个非常简单的示例,我已经能够重现冻结一分钟或更长时间。 【参考方案1】:

我找到了解决方案,而且似乎我在其他人修复 Angular 中的错误时找到了解决方案!它已在 Angular 1.3.x 中修复。

该错误位于 angular.js 代码中的“isArrayLike”。有时在赋值“var length = obj.length;”后未定义 obj.length可变长度获取值“1”。这将导致 isArrayLike 对于不是 arrayLike 的对象返回 true。这个错误尤其会破坏 angular 的 forEach 以及随后的 JQLite 的“eventHandler”。因此,发生这种情况时不会执行任何事件处理程序。

【讨论】:

这是 webkit 错误:trac.webkit.org/changeset/182058/trunk/Source/JavaScriptCore/… isArrayLike n 1.2.x 和 1.3.x 的实现除了使用全局变量外是相同的。我看到您提到了 phantom object.length 属性的 webkit 问题 - 您是否暗示如何在 1.2.x 中修补/解决此问题? 令人惊讶的是,一行代码产生了很大的不同。有时 - 并非总是 - 在分配“长度”后的 iOS8 Safari 上获取值 1 而 obj.length 未定义。这似乎是由 JIT 错误引起的。这将导致 isArrayLike 在不是 arrayLike 的对象上返回 true,这将导致对象“forEach”无法迭代对象键,因为在 forEach 实现中首先检查 isArrayLike。 forEach 未能迭代 obj 键将导致在 createEventHandler 的 forEach(eventHandlersCopy,..) 处调用 forEach 时,obj 事件处理程序不执行。

以上是关于Angular.js 移动浏览器应用程序在 iOS 8 Safari 上冻结的主要内容,如果未能解决你的问题,请参考以下文章

Angular js中的文件下载

socket.io+angular.js+express.js做个聊天应用

Angular.js 和 Fabric.js:一旦代码移动到 Angular 指令,Fabric 画布就会改变行为

ios 不断显示移动网络应用程序的加载微调器

CK2104-Angular JS 仿拉勾网 WebApp 开发移动端单页应用

socket.io+angular.js+express.js做个聊天应用