I want to make my iframes responsive. I am using angular directive with typescript to achieve that.
This is the code:
...
export class ContentDirective implements angular.IDirective {
public priority = -1;
public restrict = 'A';
public scope = {};
static $inject = [
"$window"
];
constructor(private $window, private $timeout, private $compile) {
}
public link: angular.IDirectiveLinkFn = (scope: angular.IScope, element: angular.IAugmentedJQuery, attrs: angular.IAttributes): void => {
this.handleResize(element);
};
private handleResize(element): void {
var win = angular.element(this.$window);
// Find all iframes
var $allVideos = element.find("iframe"),
// The element that is fluid width
$fluidEl = element;
// Figure out and save aspect ratio for each iframe
$allVideos.each(function () {
$(this)
.data('aspectRatio', this.height / this.width)
// and remove the hard coded width/height
.removeAttr('height')
.removeAttr('width');
});
// When the window is resized
win.resize(() => {
var newWidth = $fluidEl.width();
// Resize all iframes according to their own aspect ratio
$allVideos.each(function () {
var $el = $(this);
$el
.width(newWidth)
.height(newWidth * $el.data('aspectRatio'));
});
}).resize();
}
public static factory(): angular.IDirectiveFactory {
var directive = ($window) => {
return new ContentDirective($window);
};
directive.$inject = ['$window'];
return directive;
}
}
...
This is the part of html I am using:
...
<p ng-bind-html="body" content-directive></p>
...
"body" is angular expression with content of p tag. Iframe is in there.
The problem I have is that there isn't any iframe element inside p tag when directive start execution. When I put $timeout to wait for DOM then everything is working correctly.
How can I start execution of directive after DOM is loaded?
I found the solution here:
so the working code is looking like this:
export class ContentDirective implements angular.IDirective {
public priority = 10;
public restrict = 'A';
static $inject = [
"$window"
];
constructor(private $window) {
}
public link: angular.IDirectiveLinkFn = (scope: angular.IScope, element: angular.IAugmentedJQuery, attrs): void => {
scope.$watch(attrs.ngBindHtml, () => {
this.handleResize(element);
});
};
private handleResize(element): void {
var win = angular.element(this.$window),
// Find all iframes
$allVideos = element.find("iframe"),
// The element that is fluid width
$fluidEl = element;
// Figure out and save aspect ratio for each iframe
$allVideos.each(function () {
$(this)
.data('aspectRatio', this.height / this.width)
// and remove the hard coded width/height
.removeAttr('height')
.removeAttr('width');
});
// When the window is resized
win.resize(() => {
var newWidth = $fluidEl.width();
// Resize all iframes according to their own aspect ratio
$allVideos.each(function () {
var $el = $(this);
$el
.width(newWidth)
.height(newWidth * $el.data('aspectRatio'));
});
}).resize();
}
public static factory(): angular.IDirectiveFactory {
var directive = ($window) => {
return new ContentDirective($window);
};
directive.$inject = ['$window'];
return directive;
}
}