Skip to content
This repository has been archived by the owner on Jun 18, 2022. It is now read-only.

Load event handler should get called when backgroundImage style is rendered. #101

Open
grant77 opened this issue Jan 13, 2018 · 1 comment

Comments

@grant77
Copy link

grant77 commented Jan 13, 2018

In my application I have a file upload with an image to display what you just uploaded. I need the load event to get called reliably so that I can call URL.revokeObjectUrl. Currently, the load event is triggered by "setPlaceholder" in ofi.js and only if the previous image has different dimensions. So, sometimes load gets called and sometimes it does not. Plus, in my load event handler I have to use setTimeout before calling revokeObjectUrl or the image will not get rendered. Here is my current hack (in typescript) to make it work properly:

import objectFitImages from 'object-fit-images/dist/ofi.es-modules.js';
const OFI = 'bfred-it:object-fit-images';
const OFISymbol = Symbol(OFI);
if (!objectFitImages.supportsObjectPosition) {
    Object.defineProperty(HTMLImageElement.prototype, OFI, {
        get: function () { return this[OFISymbol]; },
        set: function (value) { return this[OFISymbol] = new OFIWrapper(value, this); }
    });
    document.body.addEventListener('load', e => {
        if (e.target instanceof HTMLImageElement) {
            if (!e.target[OFI])
                objectFitImages(e.target);
            else if (e.isTrusted)
                e.stopImmediatePropagation();
        }
    }, true);
}

class OFIWrapper {
    get img() { return this.data.img; }
    set img(imageElement: HTMLImageElement) {
        if (this.data.img != imageElement && (this.data.img = imageElement)) {
            // I'm having simalar issue dealing with same line of code mentioned in this https://github.com/bfred-it/object-fit-images/issues/85.
            // Since I dont care about srcset, we will just replace currentSrc with src
            Object.defineProperty(imageElement, 'currentSrc', { get: function () { return this.src; } }); // <== this sucks
            imageElement.addEventListener('load', this.triggerHandler.bind(this));
        }
    }
    private triggerHandler() {
        let dummy = this.owner.clientHeight; // <== FORCE REFLOW.  VERY IMPORTANT!!!!
        var event = document.createEvent('Event');
        event.initEvent('load', false, false);
        this.owner.dispatchEvent(event);
    }
    constructor(private data: any, private owner: HTMLImageElement) {
        Object.assign(this, data);
    }
}
@grant77
Copy link
Author

grant77 commented Jan 15, 2018

I went ahead and modified "bfred-it"'s code directly.

ofi.txt

With my fix, load and error handlers will fire like they do in non-IE browsers. I am also converting any objectUrls to dataUrls for the background-image. This will cover calling revokeImageUrl on load of hidden images. I also needed a fix for #85 . This fix will break srcset, but I don't need it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants