Created
July 15, 2019 08:10
-
-
Save Maqsim/6da63a617e28c87736611baafd61e0df to your computer and use it in GitHub Desktop.
Directive that waits for image is available (not 404) for some time and then set image to src="" or background-image: url()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import angular from 'angular'; | |
import { defaults } from 'underscore'; | |
interface IScope extends ng.IScope { | |
url: string; | |
backgroundImage: string; | |
showSpinner: string; | |
maxRetries: string; | |
delay: string; | |
} | |
/** | |
* Directive that waits for image is available (not 404) for some time | |
* and then set image to src="" or background-image: url() | |
*/ | |
class WaitForImageDirective implements ng.IDirective { | |
restrict: string = 'A'; | |
scope: any = { | |
url: '@waitForImage', | |
backgroundImage: '@waitForImageBackgroundImage', | |
showSpinner: '@waitForImageShowSpinner', | |
maxRetries: '@waitForImageMaxRetries', | |
delay: '@waitForImageDelay' | |
}; | |
constructor(private $timeout: ng.ITimeoutService) { | |
'ngInject'; | |
} | |
public link(scope: IScope, element: JQLite, attrs: ng.IAttributes) { | |
defaults(scope, { | |
backgroundImage: 'false', | |
showSpinner: 'false', | |
maxRetries: '3', | |
delay: '500', | |
}); | |
let suffix: string; | |
let retry = 0; | |
let latestRetriedUrl: string; | |
const setImage = (url: string) => { | |
if (!element) { | |
return; | |
} | |
if (scope.showSpinner === 'true') { | |
element.removeClass('wait-for-image_in-progress'); | |
} | |
if (scope.backgroundImage === 'true') { | |
element.css('backgroundImage', `url(${url})`); | |
} else { | |
element.attr('src', url); | |
} | |
}; | |
const image = new Image(); | |
image.onload = () => setImage(latestRetriedUrl); | |
image.onerror = () => { | |
if (scope.showSpinner === 'true') { | |
element.addClass('wait-for-image_in-progress'); | |
} | |
this.$timeout(() => { | |
if (retry < parseInt(scope.maxRetries, 10)) { | |
retry++; | |
image.src = latestRetriedUrl = scope.url + suffix + Date.now(); | |
} | |
}, parseInt(scope.delay, 10)); | |
}; | |
attrs.$observe('waitForImage', () => { | |
retry = 0; | |
suffix = (scope.url.indexOf('?') > -1 ? '&' : '?') + 't='; | |
image.src = latestRetriedUrl = scope.url; | |
setImage(scope.url); | |
}); | |
} | |
} | |
export default angular | |
.module('app.common.wait-for-image', []) | |
.directive('waitForImage', ($timeout: ng.ITimeoutService) => new WaitForImageDirective($timeout)).name; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment