create3000 / x_ite

X_ITE X3D Browser, view and manipulate X3D and VRML scenes in HTML.
https://create3000.github.io/x_ite/
Other
67 stars 15 forks source link

Dispatch DOM load event after scene is completely loaded #129

Closed andreasplesch closed 1 year ago

andreasplesch commented 1 year ago

This is a feature users regularly ask for since web programmers are used to such load events from the DOM. This really applies to Inlines due to async loading.

https://github.com/andreasplesch/x_ite_dom/blob/master/src/x_ite_dom.js#L355 dispatched an x3dload event.

The standard solution would be to add a LoadSensor to the scene but I think web programmers would expect this event to be available by default for any scene, even without a LoadSensor. An option would be to add back the embedded LoadSensor but perhaps there are other internal options ?

create3000 commented 1 year ago

I would add these lines to appendInlineChildElement:

        switch (node .checkLoadState ())
        {
            case X3DConstants .COMPLETE_STATE:
            {
                const event = new CustomEvent ("load",
                {
                    detail: { node: node ? node .valueOf () : null },
                });

                element .dispatchEvent (event);
                break;
            }
            case X3DConstants .FAILED_STATE:
            {
                const event = new CustomEvent ("error",
                {
                    detail: { node: node ? node .valueOf () : null },
                });

                element .dispatchEvent (event);
                break;
            }
        }

Would use load and error to be similar to \<image>. This should not collide with the load field, because one would use onload attribute with code.

create3000 commented 1 year ago

Added documentation:

https://create3000.github.io/x_ite/dom-integration#events-of-inline-element

andreasplesch commented 1 year ago

super.

andreasplesch commented 1 year ago

The 'load' event may be dispatched too early. I think it should be dispatched only after an Inline is completely loaded, eg. after all internal resources, including all internal inlines, are loaded.

https://raw.githack.com/andreasplesch/Library/0b3898b568d1fbaf71a59f74f7a27cdc10685a95/Tests/Browser/DOMIntegration/in_reflection/dom_inlineReflection.xhtml

has two inlines, which have inlines themselves.

After both inlines have fired 'load', a function tries to access DOM elements from the innermost inlines but fails because the DOM elements are not available.

I can put together a simpler example as well.

create3000 commented 1 year ago

Good idea, makes life much more easier. Ready to be tested.

https://raw.githack.com/andreasplesch/Library/0b3898b568d1fbaf71a59f74f7a27cdc10685a95/Tests/Browser/DOMIntegration/in_reflection/dom_inlineReflection.xhtml

andreasplesch commented 1 year ago

Looks good !