angularjsangularjs-directivebackground-imageimage-preloader

Custom directive for preloading background image not working AngularJS


I am working on a custom directive to preload images while the state (with ui-router is changing) so that both data and content are resolved before navigating to the new state.

I have created a Pen here: https://codepen.io/wons88/pen/NgbNvO to show my basic implementation with the bgSrc directive:

app.directive('bgSrc', ['preloadService', function (preloadService) {
    return function (scope, element, attrs) {
        element.hide();

        preloadService(attrs.bgSrc).then(function () {
            console.log(element.css);
            element.css({
                "background-image": "url('" + attrs.bgSrc + "')"
            });
            element.fadeIn();
        });
    }
}]);

and the preloadService:

app.factory('preloadService', ['$q', '$rootScope', function ($q, $rootScope) {
    return function (url) {
        var deffered = $q.defer(),
            image = new Image();

        image.src = url;

        if (image.complete) {
            $rootScope.loading = false;
            deffered.resolve();

        } else {
            $rootScope.loading = true;
            image.addEventListener('load',
                function () {
                    deffered.resolve();
                    $rootScope.loading = false;
                });

            image.addEventListener('error',
                function () {
                    deffered.reject();
                    $rootScope.loading = true;
                });
        }

        return deffered.promise;
    };
}]);

And the HTML:

<div bg-src="https://images5.alphacoders.com/446/thumb-1920-446028.jpg">Background img should show up...</div>

EDIT: The problem is that the image is never shown even if it is loaded (as shown in the network tab in chrome dev tools). If I make it statically applying style (or class) the image is shown no problem, just loads slower... hence trying to apply the directive.

I know there is something wrong happening in the bgSrc directive but I am unable to pinpoint it. Any help on the matter would be much appreciated :)


Solution

  • element.hide is not a function

    You are calling

    element.hide();
    

    in your link function, but jQlite does not have a hide() method. Since you did not include jQuery in your Codepen, it's failing on that line.

    https://docs.angularjs.org/api/ng/function/angular.element

    Instead, use css

    element.css('visibility', 'invisible');
    

    Or add jQuery