morzel.net

.net, js, html, arduino, java... no rants or clickbaits.

Wykrycie załadowania iframe stworzonego w Ext JS

Przypuśćmy, że zachodzi potrzeba wykonania jakiegoś fragmentu kodu w momencie załadowania zawartości iframe. W przy- padku gdy iframe jest utworzony statycznie w kodzie HTML strony, sprawa jest bardzo prosta. Wystarczy podłączyć funkcję JavaScript pod zdarzenie load:

<iframe src="http://wikipedia.org" width="600" height="400" onload="someFunction();" ></iframe>

Uwaga: zdarzenie load (onload) zostanie wywołane gdy cała zawartość dokumentu zostanie załadowana (w tym jego elementy zewnętrzne takie jak obrazki). Jeśli trzeba zadziałać wcześniej, tzn. w chwili gdy DOM jest gotowy, należy skorzystać z innych metod...

A co w przypadku iframe’a stworzonego w kodzie Ext JS?

Prostym sposobem na utworzenie go jest użycie Ext.BoxComponent z odpowiednio ustawioną wartością autoEl. Daje to możliwość łatwego wpisania iframe’a w layout Ext JS (np. jako składowej Ext.Window) bez rozszerzania drzewa dokumentu o zbędne elementy.

var iframeContainer = new Ext.BoxComponent({
    autoEl: {
        tag: 'iframe',
        frameborder: '0',
        src: 'http://wikipedia.org'
    },
    listeners: {
        afterrender: function () {
            console.log('rendered');

            this.getEl().on('load', function () {
                console.log('loaded');
            });
        }
    }
});


W powyższym kodzie (Ext JS 3.2.1) bardzo istotny jest moment, w którym pod zdarzenie load iframe’a podpinany jest handler. Można to zrobić jedynie po tym gdy kontrolka (BoxComponent) zostanie wyrenderowana. Jeśli zrobi się to wcześniej, wówczas wywołanie getEl() zwróci undefined i kod nie zadziała. Przed renderowaniem kontrolka Ext JS to jedynie obiekt JavaScript, dla którego nie istnieją żadne elementy w drzewie dokumentu. Poniżej znajdują się dwa screeny prezentujące fragmenty kodu HTML utworzonego przez Ext.Window, w którym jedynym elementem na liście items był BoxComponent tworzący tag iframe...

beforerender:

DOM beforerender

afterrender:

DOM afterrender


Widać wyraźnie, że zbyt wczesne podpinanie się pod load nie ma prawa zadziałać bo nie można przecież nasłuchiwać zdarzeń na czymś co nie isntnieje.

Powyższe zrzuty pochodzą z okna Elements narzędzia Chrome Developers Tools. Szybkim sposobem by pokazać to narzędzie (oczywiście w przeglądarce Googla) jest naciśnięcie F12 lub Ctrl+Shift+I. Fajną funkcją CDT jest możliwość wylistowania zdarzeń nasłuchiwanych na określonym elemencie DOM. By zobaczyć listę trzeba zaznaczyć element DOM i w menu po prawej stronie wybrać zakładkę Event Listeners. Na screenie poniżej widać, że iframe faktycznie posiada obsługę zdarzenia load:

CDT Event Listeners