1

我想延迟加载图像和 iframe(即一旦元素在视口中就设置 src)。我有一个现有的角度指令,当元素滚动到视图中时is-visible设置属性。is-visible如何在我的指令中重用这个set-src-when-visible指令?

即,我希望这段代码重用is-visible指令:

<img set-src-when-visible="http://example.com/img.png" />`
<iframe set-src-when-visible="http://example.com/" /> 

不满意的方法1:要求is-visible指令

我可以要求is-visible指令位于我声明set-src-when-visible指令的同一元素上:

<img set-src-when-visible="url" is-visible />

myApp.directive('setSrcWhenVisible', function () {
    return {
        restrict: 'A',
        require: 'isVisible',
        link: function ($scope, element, attrs) {
            var set = false;
            attrs.$observe('isVisible', function(isVisible) {
                if(isVisible && !set) {
                    attrs.$set('src', $scope.$eval(attrs.setSrcWhenVisible));
                    set = true;
                }
            });
        }
    }
});

这是一个工作示例:http: //jsfiddle.net/pvtpenguin/6tCk6/

缺点:我希望能够只指定set-src-when-visible指令,同时仍然重用is-visible.


不满意的方法2:

创建两个指令,一个用于 iframe,一个用于 img 标签:

<iframe set-iframe-src-when-visible="url"></iframe>
<img set-img-src-when-visible="url" />

angular.forEach(['Iframe', 'Img'], function(tagName) {
    var directiveName = 'set' + tagName + 'SrcWhenVisible';
    myApp.directive(directiveName, function ($window) {
        return {
            restrict: 'A',
            template: '<' + tagName + ' is-visible></' + tagName + '>',
            replace: true,
            link: function ($scope, element, attrs) {
                var set = false;
                attrs.$observe('isVisible', function(value) {
                    if(value && !set) {
                        attrs.$set('src', $scope.$eval(attrs[directiveName]));
                        set = true;
                    }
                });
            }
        }
    });
});

工作示例:http: //jsfiddle.net/pvtpenguin/K4JuC/2/

缺点:每个指令的名称不同,而且这不适合我用来声明和配置我的应用程序的方法。

4

1 回答 1

1

根据我们的评论讨论,这是一个链接功能,希望能满足您的需求:

link: function ($scope, element, attrs) {
   $scope.src = attrs.setSrcWhenVisible;  // save attribute -- is $eval needed?
   var tagName = element[0].tagName;
   if(tagName == 'IMG') {
      var jqLiteWrappedElement = angular.element('<img is-visible></img>');
   } else {
      var jqLiteWrappedElement = angular.element('<iframe is-visible></iframe>');
   }
   element.replaceWith(jqLiteWrappedElement);
   $compile(jqLiteWrappedElement)($scope);
   var set = false;
   attrs.$observe('isVisible', function(value) {
      if(value && !set) {
         attrs.$set('src', $scope.src);
         set = true;
      }
   });
}

小提琴

于 2013-05-06T16:52:07.057 回答