我想延迟加载图片和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/" />
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
指令。
创建两个指令,一个用于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/
下行:每个指令的名称不同,加上这与我用于声明和配置我的应用的方法不相符。
答案 0 :(得分: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;
}
});
}