• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Frage eigene JS-Library / nicht-nachvollziehbares Problem / if-Statement für nicht-existentes DOM-Element falsch?

xSTVNx

Mitglied
Ich versuche mir selber eine kleine JavaScript-Library zu schreiben, da mir jQuery zunehmend als völlig überladen erscheint, und ich schlichtweg ein besseres Verständnis vom Dahinter bekommen möchte. Das klappt soweit eigtl. sehr gut, allerdings stehe ich grade vor einem nicht nachvollziehbaren Problem:

Ich bin dabei eine inc()-Funktion zu schreiben mit ich wahlweise eine CSS- bzw. JS-Datei zum <head> hinzufügen kann, was auch funktioniert, jedoch möchte ich, dass sie außerdem in der Lage ist, eine CSS- bzw. JS-Datei auszutauschen (je nachdem welche der angebenen Dateien eingebunden ist, quasi so togglemäßig), was nicht vollständig gelingt.

Anmerkung: Vom $-Symbol nicht täuschen lassen, ich habe hier kein jQuery eingebunden! (Der Code zur Deklaration meiner Library folgt weiter unten noch.)

Javascript:
function inc(a,b=null){
  if( b === null ){
    if( a.endsWith('.css') ){
        // include css file (funktioniert)
        $('head').ap('<link rel="stylesheet" href="'+a+'" type="text/css" />');
    } else if( a.endsWith('.js') ){
        // include js file (funktioniert)
        $('head').ap('<script src="'+a+'"></script>');
    }
  } else {
    if( a.endsWith('.css') && b.endsWith('.css') ){
      // switch (replace) css files
      if( $('link[href="'+b+'"]') ){ // Markierung 1 (siehe unten)
        $('link[href="'+b+'"]').at('href',a); // Markierung 2 (siehe unten)
      } else if( $('link[href="'+a+'"]') ){
        $('link[href="'+a+'"]').at('href',b);
      }
    } else if( a.endsWith('.js') && b.endsWith('.js') ){
      // switch (replace) js files (noch nicht fertiggestellt, da es ja noch an anderer Stelle hapert, also im Moment irrelevant)
      $('script[src="'+b+'"]').at('href',a);
    }
  }
}

// zur Anwendung soll das dann so kommen:

inc('beispiel.css'); // bindet eine CSS-Datei ein
inc('beispiel.js'); // bindet eine JS-Datei ein
inc('adam.css','eva.css'); // switcht zwischen 2 CSS-Dateien (je nachdem, welche existiert, wird sie dann durch die andere ersetzt)

##################################################

Ums mal konkret zu machen – Ausgangspunkt ist folgendes HTML, bei dem es einen Schalter gibt, mit dem man zwischen Tagmodus (helles Design) und Nachtmodus (dunkles Design) switchen kann. Voreingestellt ist der Tagmodus bzw. das helle Design.

HTML:
<!DOCTYPE html>

<html dir="ltr" lang="de-DE">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="layout.css" type="text/css" />
    <link rel="stylesheet" href="light.css" type="text/css" />
    <title>Beispiel</title>
</head>

<body>
    ...

    <div id="stylemode">
        <span>Tagmodus</span>
        <img id="switch" src="switch-a.svg" />
        <span>Nachtmodus</span>
    </div>

</body>

</html>

Mein JS-Code dafür sieht nun wie folgt aus:
Javascript:
$('#switch').on('click',function(){
    $('#switch').at('src','switch-b.svg','switch-a.svg'); // switcht die Schaltergrafik(en) aus – funktioniert 1A
    inc('dark.css','light.css'); // funktioniert nur einmalig (Erläuterung folgt nun)
});

In diesem Beispiel gelingt es beim ersten Klick, dass die light.css durch die dark.css ersetzt wird. Wenn ich dann aber wieder auf den Schalter klicke, funktioniert es nicht, stattdessen vermeldet die die Konsole: TypeError: x is null

Das hängt offenbar damit zusammen, dass das DOM-Element nicht existiert. Und genau hier hört mein Verständnis der Nachvollziehbarkeit des Problems auf, denn die Konsolte vermeldet den Fehler nicht in der Zeile mit der Markierung 1, sondern der Markierung 2. Aber in der Zeile mit der Markierung 1 befindet sich doch ein if-Statement, also wird doch bei nicht Existenz des DOM-Elements die nachfolgende Zeile mit der Markierung 2 garnicht durchlaufen?!?!

Ich habe außerdem in der Zeile mit der Markierung 1 alle möglichen Varianten probiert wie bspw. if( $('link[href="'+b+'"]') !== null ){ usw.

Der Code zur Konstruktion der relevanten Teile meiner Library ist wie folgt:

Javascript:
D = document;
W = window;

var $ = function(s) {
  var x;

  var obj = {

    myLibrary(s){
      if (x) return x;
      return D.querySelector(s);
    },

    // append
    ap(a){
      x.appendChild(a);
      return this;
    },

    // attribute: GET & SET (& SWITCH)
    at(a,b=null,c=null){
      if( b !== null && c !== null ){ // SWITCH – at('data-beispiel','irgendein wert','irgendein anderer wert');
        if( x.getAttribute(a) !== b ){
          x.setAttribute(a,b);
        } else {
          x.setAttribute(a,c);
        }
        return this;
      } else if( b !== null && c === null ){ // SET – at('data-beispiel','irgendein wert');
        x.setAttribute(a,b);
        return this;
      } else { // GET  – at('data-beispiel');
        return x.getAttribute(a);
      }
    },

    // on = addEventListener
    on(a,b){
      return x.addEventListener(a,b);
    }

  };

  x = obj.myLibrary(s);
  return obj;
};

Danke schonmal für jegl. Hilfe! :)
 
Zuletzt bearbeitet:
Werbung:
Zurück
Oben