AngularJS实现图片完全渲染后启用按钮的技术问题
解决AngularJS中图片完全渲染后启用按钮的问题
我完全懂你的困扰——之前用的image-on-load指令监听的load事件,只是告诉我们图片的二进制数据已经下载完成,但浏览器还没把它实际绘制到页面上,这就导致按钮总是提前变可用。要实现图片完全渲染完成后再启用按钮,我们得利用浏览器的重绘机制来精准判断时机。
核心解决方案:结合load事件与requestAnimationFrame
requestAnimationFrame是浏览器提供的API,它会在浏览器即将执行下一次重绘前调用回调函数。我们可以在图片load事件触发后,通过它来等待浏览器完成图片的渲染绘制,确保这时候再启用按钮。
修改后的指令代码如下:
angular.module("fb_totem") .directive('imageOnLoad', function($window) { return { restrict: 'A', link: function(scope, element, attrs) { element.bind('load', function() { // 嵌套两层requestAnimationFrame确保重绘完成 $window.requestAnimationFrame(function() { $window.requestAnimationFrame(function() { scope.$apply(function() { // 用$eval执行绑定的函数,更符合Angular上下文 scope.$eval(attrs.imageOnLoad)(true); }); }); }); }); element.bind('error', function(){ scope.$apply(function() { scope.$eval(attrs.imageOnLoad)(false); }); }); } }; })
为什么要嵌套两层?
第一次requestAnimationFrame会在浏览器准备重绘前触发,第二次则会在重绘完成后触发——这能确保我们的回调是在图片已经完全渲染到页面之后执行,完美解决了之前提前启用按钮的问题。
控制器与页面标记调整(可选优化)
你的控制器代码基本不用改,不过可以稍微优化一下逻辑可读性:
angular.module("fb_totem") .controller('mycontroller', function($scope){ $scope.loading = true; $scope.ImgLoaded = function(isSuccess){ // 根据图片加载/渲染结果更新状态 $scope.loading = !isSuccess; } })
页面标记保持原样即可,确保image-on-load指令绑定到正确的函数:
<img image-on-load="ImgLoaded" ngf-thumbnail="url_mobilePhoto"/> <button type="button" ng-click="cancel()" ng-disabled="loading">Some Action</button>
这个方案能精准判断图片是否已经完全渲染到页面,而不是仅仅加载完成,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Luiz Alves
相关产品推荐
相关产品推荐

