Dieser Leitfaden soll einen kurzen Überblick geben, über die Funktion, das Verhalten und die grundlegenden Verwendungsmöglichkeiten der Icony JS-API.

Um die Icony JS-API zu verwenden, fügen Sie einfach den folgenden kurzen JavaScript-Code in einen <script>-Block im <head>-Bereich Ihrer Seite ein:

(function(i,c,o,n,y,j,s){i['IconyObject']=y;i[y]=i[y]||function(){function b(a){
return a?(a^Math.random()*16>>a/4).toString(16):'i'+([1e7]+1e7).replace(/[018]/g,b)+1*new Date}
var k=arguments;k.id=b();(i[y].q=i[y].q||[]).push(k);if(i[y].R){i[y].R()};return k.id;};
j=c.createElement(o),s=c.getElementsByTagName(o)[0];j.async=1;j.src=n;s.parentNode.insertBefore(j,s)
})(window,document,'script','//js.icony.com/api.js','icony');
icony('create', 'myPlatformId');

Bei der Ausführung erzeugt der Code eine neue, globale Funktion mit dem Namen icony und lädt die API-Bibliothek asynchron nach. In der folgenden Zeile wird die create-Methode aufgerufen, um Ihre Seite bei der Icony JS-API zu registrieren.

Die globale icony-Funktion ist die einfachste Möglichkeit um mit der API-Bibliothek zu kommunizieren. Die Funktion akzeptiert mehrere Parameter, wobei der erste Parameter eine API-Methode repräsentiert. Eine einfache Anfrage könnte beispielsweise so aussehen:

icony('get', 'tips', 'json', myCallback, {count:10});

Da die API-Bibliothek asynchron geladen wird, wurde die icony-Funktion so gestaltet, dass sie auch verwendet werden kann, bevor die Bibliothek vollständig geladen wurde. Zu Beginn werden alle Methoden-Aufrufe auf einen Stapel gelegt. Wenn die Bibilothek fertig geladen wurde, wird der Methoden-Stapel abgearbeitet; alle weiteren Methoden-Aufrufe werden dann sofort ausgeführt. Dadurch müssen sich Sie als Entwickler weniger Gedanken um die asynchrone Natur der Icony JS-API machen.

Für bestimmte Anfragen wird eine Antwort des API-Servers erwartet. Bei asynchronen APIs wie dieser, kann aber nur mittels eines Callbacks auf Antworten reagiert werden. Daher wird schon beim Stellen der Anfrage (d.h. beim Aufruf der globalen icony-Fuktion mit einer entsprechenden Methode) eine spezielle Funktion an die Biliothek übergeben. Diese registriert sich selbst als Callback-Funktion und wird automatisch ausgeführt, sobald die Antwort des Servers eintrifft.

Bei der Icony JS-API entspricht diese Antwort immer einem festgelegten Format. Jeder Callback-Funktion wird daher bei Ihrem Aufruf genau ein Argument übergeben, das alle Daten enthält und ausgwertet werden kann:

var myCallback = function (response) {
  console.log("Received response @ "+response.time);
  document.addEventListener("DOMContentLoaded", function(event) {
    document.getElementById("myElement").appendChild(response.data);
  });
};

Sobald die Callback-Funktion myCallback aufgerufen wird, erhält sie über den Paramter response die API-Antwort. In der zweiten Zeile wird der Zeitpunkt der Antwort in das Log der JavaScript-Console geschrieben; die vierte Zeile fügt einen in response.data gespeichteren DOM-Node in die Seite ein sobald der DOM bereit ist.

Hinweis: Änderungen am DOM sollten erst durchgeführt, wenn dieser bereit ist. Führen Sie DOM-Manipulationen daher nur durch, wenn Sie sich dessen sicher sein können. Nutzen Sie dafür z.B. das DOMContentLoaded-Event oder spezielle Funktionen einer JavaScript-Bibilothek. (Beispiel jQuery: $(document).ready(handler))

Callback-Funktionen bieten die größtmögliche Flexibilität im Bezug auf die Auswertung der Antworten. Vor allem in Kombination mit Antwortdaten im json-Format, sind Ihnen bei der Darstellung der Ergebnisse kaum Grenzen gesetzt. Einige kreative Vorschläge finden Sie bei den Beispielen.

Widgets bieten Ihnen die Möglichkeit weitere Interaktionen in Ihrer Seite zu integrieren. Im Wesentlichen können Sie unter einem Widget daher ein Script verstehen, dass einen eigentlich statischen Inhalt dynamisch darstellt. So kann beispielsweise eine lange Liste von Benutzeraktivitäten so dargestellt werden, dass immer nur ein kleiner Teil der Aktivitäten angezeigt wird; das Widget-Script würde dafür Sorge tragen, dass die Anzeige durchwechselt.

Auch wenn aktuell nur ein Widget für das Aktivitäten-Modul zur Verfügung steht, soll dieser Bereich in Zukunft erweitert werden. Falls Sie Ideen oder Wünsche für bestimmte Widgets haben, nehmen Sie gerne Kontakt mit uns auf.

icony('script', 'activities', 'native');
icony('set', 'activities', 'pause', 2000);

document.addEventListener("DOMContentLoaded", function(event) {
  var myActivitiesId = icony('get', 'activities', 'dom', function(response) {
    document.getElementById("myActivitiesWidget").appendChild(response.data);
  }, {count: 50, css_prefix: 'icony_'});

  icony('set', myActivitiesId, 'show', 7);
});

Bei der Einbindung eines Widgets müssen mehrere Punkte beachten werden. Zu erst einmal wird ein normales Modul geladen, das als Basis für das Widget dient (Zeile 5-7). Darüberhinaus muss das oben erwähnte Widget-Script geladen werden (Zeile 1).

Zuletzt kann das Verhalten von Widgets über spezielle Variablen beeinflusst werden. Die Einstellungen erfolgen dabei entweder mittels ID für einzelne, konkrete Widgets (Zeile 9) oder alle Widgets eines Moduls (Zeile 2). Auch Widgets sind vollständig asynchron konzipiert; es ist egal ob zuerst das Widget-Script oder das Modul geladen wird. Variablen können können gesetzt werden, sobald die requestId eines Moduls bekannt ist und jederzeit wieder geändert werden (Einstellungen für alle Widgets eines Moduls, können somit zu jedem beliebigen Zeitpunkt gesetzt und geändert werden.)

Sobald ein Widget-Script und die nötigen DOM-Elemente im Dokument verfügbar sind, wird das Widget automatisch geladen und gestartet werden. Unter Umständen kann dieses Verhalten nicht erwünscht sein und deshalb über das Feld auto_load abgestellt werden. In diesem Fall kann das Widget manuell ausgeführt werden.

icony('script', 'activities', 'native');

document.addEventListener("DOMContentLoaded", function(event) {
  var myActivitiesId = icony('get', 'activities', 'dom', function(response) {
    document.getElementById("myActivitiesWidget").appendChild(response.data);
    new icony.s[response.type].o(response.request_id, response.options.css_prefix);
  }, {count: 50, css_prefix: 'icony_', auto_load: 0});
});

In Zeile 6 wird ein neues Widget-Objekt erzeugt, wobei icony.s[response.type].o den Konstruktor für das aktuelle Modul referenziert; in diesem Fall also activities. Eben dieser String ist auch in response.type enthalten. Der Konstruktor wird mit zwei Parameter aufgerufen: Der eindeutigen ID der Anfrage und dem gewählten CSS-Prefix. Beide Werte sind im response-Objekt der get-Anfrage enthalten. Isoliert betrachtet sieht der Aufruf wie folgt aus:

var widget = new icony.s[moduleName].o(requestId, cssPrefix);

Wobei moduleName der String für das gewünschte Modul ist bzw. diesen enthält.

Parameter

Rückgabewert

  • Object widget - Ein Widget-Objekt.

Hinweis: Beachten Sie, dass die Klasse für das Widget-Objekt durch das zugehörige Script bereitgestellt wird und erst zur Verfügung steht, wenn der Aufruf in Zeile 1 vollständig abgeschlossen wurde.

Insbesondere während der ersten Einrichtung können Probleme mit dieser API auftreten, die ohne zuätzliche Informationen nur schwer zu beheben sind. Deswegen können Sie einen Debugging-Modus aktivieren, wenn Sie in einer get-Anfrage zusätzlich das Feld debug mit angeben. Dieser Modus unterstützt Sie dabei, Fehler zu finden und zu beheben.

Ein Unterschied zum produktiven Einsatz besteht in sofern, dass Fehlermeldungen zurückgegeben werden und das serverseitige Caching der Inhalte ausgeschaltet wird. Besonders der Caching-Mechanismus kann bei fehlerhafter Konfiguration zu Problemen führen. (Es werden z.B. falsche oder keine Daten ausgeliefert, solange ein fehlerhafter Cache noch gültig ist.) Mit Verwendung des Debugging-Modus können solche Probleme umgangen werden.

Ist der Modus aktiv, werden Fehlermeldungen normalerweise an die JavaScript-Konsole Ihres Browsers gesendet. Wurde jedoch als Format json angegeben, enthält die Anfrage-Antwort ein Fehler-Objekt im data-Feld.

Achtung: Denken Sie daran, den Debugging-Modus für den produktiven Einsatz wieder zu deaktivieren. Andernfalls können fehlerhafte Daten ausgespielt werden.

Beispiel-Verwendung

icony('get', 'tips', 'json', myCallback, {count:10, debug: 1});

Beispiel-Fehlermeldungen

Ausgabe in der JavaScript-Konsole:

'ICONY_JS_API_ERROR: Required field "css_prefix" for API type "activities" with format "dom" is missing.'

Fehler-Objekt im data-Feld der Anfrage-Antwort:

response.data = {
  error: "1",
  message: 'ICONY_JS_API_ERROR: Required field "css_prefix" for API type "activities" with format "dom" is missing.'
}

Bei der Nutzung unserer API werden Sie sich vielleicht irgendwann einmal die Frage stellen, was der Unterschied zwischen Feldern und Variablen ist. Dies soll hier beantwortet werden. Zuerst aber eine wichtige Gemeinsamekeit: Sowohl Felder, als auch Variablen können einen Wert annehmen, auf den dann in einer definierten Weise reagiert wird.

Grundsätzlich gilt, bei Anfragen werden Felder verwendet; und bei Widgets Variablen. Der eigentliche Hauptunterschied liegt jedoch in ihrem Gültigkeitsbereich. Während sich die Relevanz von Felder auf den API-Server beschränkt, werden Variablen ausschließlich lokal genutzt.

Konkret bedeutet das, dass Felder bei Anfragen den API-Server mitgesendet und dort explizit ausgewertet werden. Die Antwort der API hängt unmittelbar mit den Werten der Felder zusammen und bei bestimmten Feldern ist die Angabe sogar verpfichtend notwendig. Ihre Gültigkeit ist immer auf eine konkrete Anfrage beschränkt.

Im Gegensatz dazu können Variablen zusätzlich auch mit einem Wert für alle Widgets eines Moduls belegt werden. Sie sind prinzipiell optional und außerdem tatsächlich variabel. D.h. der Wert einer Variablen kann zu jedem beliebigen Zeitpunkt geändert werden.

In dieser Rubrik werden einige spezielle Themen und Techniken behandelt, die bei der Verwendung der Icony JS-API für Sie relevant sein könnten. Wir versuchen auch den Bereich regelmäßig zu erweitern.

In modernen Webseiten werden viele Skripte und Grafiken verwendet, welche die Ladezeit stark verlangsamen können. Unter Umständen macht es daher Sinn bestimmte Elemente einer Seite erst zu laden, wenn Sie im Viewport des Besuchers sichtbar sind.

Hier sehen Sie eine kleine Demonstration, wie Sie auch die Module und Widgets der Icony JS-API mit der lazy loading Technik verwenden können.

HTML

<div id="myModuleContainer"></div>

JavaScript (Inspiriert von Echo.js)

/* Stapel für LazyLoader Objekte */
var loaderStack = [];

/* Überprüfung ob ein Element im Viewport ist */
var inViewport = function (ele) {
  var coords = ele.getBoundingClientRect();
  return ((coords.top >= 0 && coords.left >= 0 && coords.top)
         <= (window.innerHeight || document.documentElement.clientHeight));
};

/* Überprüft Sichtbarkeit für jedes Modul/Element */
var checkModules = function () {
  for (var i=0; i < loaderStack.length; i++) {
    var current = loaderStack[i];
    if (inViewport(current.elem)) {
      if (loaderStack.indexOf(current) !== -1) {
        loaderStack.splice(i, 1);
      }
      current.cb();
    }
  }
};

/* LazyLoader: Konstruktor */
var LazyLoader = function (elem, cb) {
  this.elem = elem;
  this.cb = cb;
  this.listen();
};

/* LazyLoader: Prototype */
LazyLoader.prototype = {
  init: function() {
    loaderStack.push(this); // lege Objekt auf den Stapel
  },

  /* Lausche auf onload- und onscroll-Event*/
  listen : function() {
    if (document.addEventListener) {
      document.addEventListener('DOMContentLoaded', checkModules, false);
    } else {
      window.onload = checkModules;
    }
    window.onscroll = checkModules;
  }
};

/* Erzeuge LazyLoader-Objekt */
document.addEventListener("DOMContentLoaded", function(event) {
  new LazyLoader(document.getElementById("myModuleContainer"), function() {
    icony('get', 'search', 'dom', function (response) {
      document.getElementById("myModuleContainer").appendChild(response.data);
    }, {css_prefix: 'icony_'});
  }).init();
});

Ausgabe (Zusätzlich verzögert um 1 Sekunde)