JavaScript Data Attribute von <script> Element dynamisch verändern.

jb_alvarado

Lt. Junior Grade
Registriert
Sep. 2015
Beiträge
491
Hallo Allerseits,
kurz zum Hintergrund:

Ich habe einen Telegram Channel erstellt, diesen lasse ich mit einem selbst programmierten Bot überwachen. Wenn eine neue Nachricht herein kommt, schreibt der Bot diese in eine Datenbank.
Mit einer simplen API kann ich die Datenbank abfragen und mir die letzte Message ID ausgeben.

Den Aufwand betreibe ich, weil ich auf einer Webseite immer den letzten Post darstellen möchte. Telegram biete nur die Möglichkeit an einen Post mit auszugeben und zwar mit:

HTML:
<script async src="https://telegram.org/js/telegram-widget.js?19" data-telegram-post="telegram/83" data-width="100%"></script>

Jetzt müsste ich allerdings per JS das data-telegram-post verändern. Bekomme ich auch hin, mit:

Javascript:
async function getLastPost() {
    const response = await fetch('https://example.org/api/posts?fields=postId&limit=1');
    const json = await response.json();

    if (json.data.length > 0) {
        return json.data[0].postId;
    }

    return 0;
}

async function processTelegram () {
    const lastPost = await getLastPost();
    const scriptData = document.querySelector('[data-telegram-post]');

    if (lastPost > 0) {
        scriptData.dataset.telegramPost = `my-channel/${lastPost}`;
    }
}

processTelegram()

Allerdings wird so mein Widget nicht angezeigt. Ich vermute weil ich es mit data-telegram-post="" initialisiere, und später den Wert überschreibe.
Das Element müsste also entweder später initialisiert werden, wenn es schon seine Werte hat, oder grundsätzlich mit den korrekten Daten erstellt werden.

Habt ihr eine Idee, wie ich das hinbekomme?
 
Zuletzt bearbeitet:
Wenn du das Skript nicht initial laden willst, dann schreib kein <script> Tag in dein HTML, sondern bau dir ein Script Tag in JavaScript zusammen, wenn du alle nötigen Daten dazu gesammelt hast, und füge das dann zum DOM hinzu.
 
  • Gefällt mir
Reaktionen: jb_alvarado
Das kann man auf ganz unterschiedliche Arten lösen, die wenigsten Änderungen musst du wahrscheinlich machen, wenn du das Script mit defer lädst (z.B <script src="https://telegram.org/js/telegram-widget.js?19" data-telegram-post="telegram/83" data-width="100%" defer></script>)
 
  • Gefällt mir
Reaktionen: jb_alvarado
Ich danke euch für die Ideen! Defer hat nicht geklappt, aber das Hinzufügen per JS wie @benneq vorgeschlagen hat schon.
 
du kannst script tags auch mit id oder class attributen versehen und dann selektieren wie andere html elemente.

HTML:
<script id="telegram-widget-script" async src="https://telegram.org/js/telegram-widget.js?19" data-telegram-post="telegram/83" data-width="100%"></script>

Javascript:
var telegram_widget_script_tag = document.getElementByID('telegram-widget-script');

telegram_widget_script_tag.dataset.telegramPost = 'telegram/84';
 
  • Gefällt mir
Reaktionen: Der Lord
ah achso xD
dann so:
Javascript:
var telegram_widget_script_tag = document.getElementByID('telegram-widget-script'),
    new_telegram_widget_script_tag = document.createElement('script');

new_telegram_script_tag.dataset.telegramPost = 'telegram/84';
new_telegram_script_tag.src = telegram_widget_script_tag.src;

telegram_widget_script_tag.remove();
document.body.appendChild(new_telegram_widget_script_tag);
 
Optional lässt sich das fertige laden mit Events abhandeln:

Javascript:
new_telegram_script_tag.onload = function(){
  console.log('new_telegram_script_tag loaded');
};
new_telegram_script_tag.onerror = function(error){
  console.error('Error loading new_telegram_script_tag: ' + error);
};

alternativ gibt es noch fetch() das direkt promises zur verfügung stellt:
https://code-boxx.com/dynamically-load-javascript/
 
Zuletzt bearbeitet:
Danke @netzgestaltung! Im Grunde habe ich es auch schon so ähnlich gelöst wie du vorher geschrieben hast. Habe noch eine Benutzereinwilligung eingebaut, weil Telegram Cookies erstellen möchte.

Allerdings habe ich noch das Problem, dass mein API Request im Browser gecached wird, und somit die Posts sich nicht aktualisieren. Liegt vermutlich an den Nginx Einstellungen.
 
du kannst dazu der URL einen aktuellen timestamp parameter ?v=<unixtime> hinzufügen um etwaiges caching auszuhebeln. Mußt dir halt anschauen was jeweils die beste Möglichkeit bez caching ist.
 
  • Gefällt mir
Reaktionen: jb_alvarado
Zurück
Oben