Alex
Alex

Reputation: 2062

Angularjs - Directive to remove element flickering before completion

I'm trying write a directive to remove an img element if ng-src results in 404. The directive works, but the broken img appears for a second and then being removed. I'm trying to remove the element before it is rendered in the GUI.

TS:

import { IDirective } from "angular";

/* @ngInject */
export function imgSrcErr($http): ng.IDirective {
    return {
        link: (scope, element, attrs) => {
            element.bind("error", () => {
                element.parent().remove();
                console.log("error");
            });
        }
    };
}

Html:

<img img-src-err ng-src="{{$ctrl.model.pictureUrl}}"/>

Upvotes: 1

Views: 44

Answers (2)

jknotek
jknotek

Reputation: 1864

You may want to consider having the image hidden by default (either with CSS, or by directly manipulating the element with setAttribute('display', 'none')), then displaying it after it loads successfully.

Something like this:

imageElement.onload = function() {
    imageElement.setAttribute('display', 'inline');
}

Note: The image may already be loaded before the event handler is set (e.g. the image was loaded from the cache), in which case the handler won't fire. To get around this, you can check to see if the image is already loaded before attaching the event handler.

Upvotes: 1

Petr Averyanov
Petr Averyanov

Reputation: 9476

You can may some workaround, e.g. set opacity to 0 while loading:

link: (scope, element, attrs) => {
    element.addClass('opacity-0');
    element.bind('error', () => {
        element[0].remove(); // not sure why you remove parent of element, but up to you
    });
    element.bind('load', () => element.removeClass('opacity-1'));
}

opacity-0 {
  opacity: 0;
}

Upvotes: 1

Related Questions