Klasa ładowana ansynchronicznie - zewnętrzny resource

Odpowiedz Nowy wątek
2019-06-19 14:06
0
<script type="text/javascript" src="https://static.example.com/script.min.js"></script>
<script type="text/javascript">
var myClass = new MyClass({
    selector: '.page-class'
});

Mam takie coś jak wyżej i działa to prawidłowo. Chciałbym jednak to przepisać na wersje podobną jak stosuje GA i inne podobne. Chodzi o asynchroniczność, ale też względy praktyczne - łatwiej instalować taki skrypt w CMSach gdzie czasami można wkleić tylko kod JS bez znaczników script.

<script type="text/javascript">
(function() {
    var sc = document.createElement('script'); sc.async = true; sc.type = 'text/javascript';
    sc.src = 'https://static.example.com/script.min.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(sc, s);
})();

// nie mam dostępu do klasy

To czemu nie mam dostępu - mniej więcej dla mnie jest zrozumiałe, tylko pytanie czy jestem w stanie to obejść? Oczywiście dostęp i możliwość zmiany czegoś w script.js mam.

edytowany 4x, ostatnio: eBizo, 2019-06-19 14:07

Pozostało 580 znaków

2019-06-19 14:29
0
s.onload = function() {
  // tutaj powinieneś mieć dostęp do klasy
};

Pozostało 580 znaków

2019-06-19 17:03
0

Niestety nie działa.

MyClass is not defined

Może ma wpływ na to jak sam plik z klasą wygląda?

(function() {
    var MyClass= function(opts){
        window.addEventListener('DOMContentLoaded', () => {
            // atrybuty, config itp
            init(this);
        })
    };

   // inne metody
edytowany 1x, ostatnio: eBizo, 2019-06-19 17:03

Pozostało 580 znaków

2019-06-19 17:09
0

Deklarujesz zmienną lokalną - siłą rzeczy nie będzie widoczna poza tą funkcją.


Pozostało 580 znaków

2019-06-19 19:17
0

Zapomniałem o najważniejszym, na końcu jest

window.MyClass = MyClass;

Tak jak pisałem na początku, przy wersji z ładowaniem script przez url działa wszystko bez problemu.

edytowany 1x, ostatnio: eBizo, 2019-06-19 19:17

Pozostało 580 znaków

2019-06-23 22:06
0

@up

Pokaż jak ten kod wygląda w całości, tak po fragmentach to niewiele można powiedzieć. - m31 2019-06-23 22:54
Ale ja ten kod dostosuje do potrzeb więc jego obecna forma i "ciało" klasy jest totalnie nieistotna. Po prostu chce mieć do niej dostęp, a jak ona wygląda i jakie metody implementuje nie jest znaczące dla problemu widoczności. - eBizo 2019-06-23 23:10
@eBizo: Ma znaczenie w którym miejscu próbujesz się do niej odwołać. Nie potrzebuję całego kodu, a jedynie miejsca gdzie ładujesz skrypt, gdzie deklarujesz klasę i miejsce gdzie ją wywołujesz. - m31 2019-06-23 23:12
Dodałem poniżej kod klasy, to jest to samo co wyżej tylko zapomniałem tam o przypięciu do window. - eBizo 2019-06-23 23:13

Pozostało 580 znaków

2019-06-23 23:06
0

Jeżeli nie masz zupełnie kontroli nad tym wstrzykiwanym kodem ale wiesz, że definiuje on finalnie window.MyClass to możesz zrobić jakiś interval który będzie sprawdzał co X milisekund czy ten obiekt istnieje, jeżeli tak to dopiero wykona na nim jakiś kod - nie jest to dobre rozwiązanie, lepiej się podpiąć pod onload jak wspominał kolega wyżej albo coś takiego.

setInterval(() => {
   if (window.hasOwnProperty('MyClass')) {
      console.log('Już mam dostęp do MyClass');
   }
}, 100);

ew. możesz wykorzystać MutationObserver, chociaż nie jestem pewny czy nasłuchiwanie na całe window nie zrobi zamieszania.

Edit. jak masz dostęp do zrób to co napisał @Patryk27 tj.

<script type="text/javascript">
(function() {
    var sc = document.createElement('script'); sc.async = true; sc.type = 'text/javascript';
    sc.src = 'https://static.example.com/script.min.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(sc, s);
    sc.onload = function() {
       console.log('Już mam dostęp do MyClass (chyba, że ten script wygląda jakoś dziwnie, wtedy nie mam ;)');
    }
})();
</sciprt>
edytowany 2x, ostatnio: Markuz, 2019-06-23 23:14
Napisałem w pierwszym poście, że to mój plik. - eBizo 2019-06-23 23:11
@eBizo: zaktualizowałem post - Markuz 2019-06-23 23:14

Pozostało 580 znaków

2019-06-23 23:12
0

Daje "cały" kod klasy (zawartość pliku js).

(function() {
    var MyClass= function(opts){
        window.addEventListener('DOMContentLoaded', () => {
            // atrybuty, config itp
            init(this);
        })
    };

    window.MyClass = MyClass;

});

Próba wywołania tej klasy na innej stronie jest pokazana na początku tematu.

edytowany 3x, ostatnio: eBizo, 2019-06-23 23:16

Pozostało 580 znaków

2019-06-23 23:26
m31
0
function initClass(Cls) {
    var myClass = new Cls({
        selector: '.page-class'
    });
}

(function() {
    var sc = document.createElement('script'); sc.async = true; sc.type = 'text/javascript';
    sc.src = 'https://static.example.com/script.min.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(sc, s);

    sc.addEventListener('load', () => { initClass(window.MyClass)})
})();

Tylko zdajesz sobie sprawę, że to:

window.addEventListener('DOMContentLoaded', () => {
            // atrybuty, config itp
            init(this);
        })

Prawdopodobnie nigdy się nie odpali. Kiedy skrypt z klasą zdąży się ściągnąć i sparsować to event DOMContentLoaded już dawno został wyemitowany.

Pozostało 580 znaków

2019-06-23 23:32
0

Oki, podaje przykłady na żywo:

Wersja w load działa ale przekazuje "pusty obiekt" (patrz konsola):
http://ebizo.pl/temp/file.html

A tu wersja z normalnym script src:
http://ebizo.pl/temp/file2.html

Pozostało 580 znaków

2019-06-23 23:39
m31
0
eBizo napisał(a):

Oki, podaje przykłady na żywo:

Wersja w load działa ale przekazuje "pusty obiekt" (patrz konsola):
http://ebizo.pl/temp/file.html

A tu wersja z normalnym script src:
http://ebizo.pl/temp/file2.html

Wywal DOMContentLoaded, przecież twój skrypt ściągnie się już PO tym jak DOMContentLoaded został wyemitowany. Dlatego funkcje z klasy nigdy się nie wywołują

(function(){

    var MyClass = function(opts){
            this.options        = [1, 2];
            console.log('TURN ON');
    };

    // make accessible globally
    window.MyClass = MyClass;

})();
Brzmi logicznie, sprawdzę to, ale od razu wytłumaczę po co tam to wstawiłem. Nie zawsze jest możliwość, aby skrypt był wstawiony w stopce więc dla pewności chciałem zapewnić dostęp do drzewa DOM, które jest wymagane, aby klasa się pod niego podpieła). - eBizo 2019-06-24 14:07

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0