Schreiben von autonomerem JavaScript

Avatar of Matt Holt
Matt Holt am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der folgende Beitrag wurde von Matt Holt von SmartyStreets verfasst. Matt schrieb mir über ein neues Plugin, das sie zur Adressverifizierung entwickelt haben, da er wusste, dass wir uns hier schon einmal mit Adressentricksereien beschäftigt haben. Er wollte nicht so sehr ihr Produkt bewerben, sondern eine Philosophie der Plugin-Entwicklung teilen, aber ich dachte, ein Gastbeitrag könnte beides tun. Er hat zugestimmt.

Straßenadressen sind kompliziert. Sie sollten einfach sein.

Sie sind schwierig, weil

  1. Eine Adresse ist keine einzelne Dateneinheit; sie besteht aus 2 bis 6 verschiedenen Teilen
  2. Adressen sind unregelmäßig und unvorhersehbar (können nicht mit regulären Ausdrücken abgeglichen werden)
  3. Eine Adresse kann quasi gültig sein, ohne vollständig gültig zu sein
  4. Adressen sind oft eine Quelle der Verwirrung für Kunden beim Checkout

Bei SmartyStreets haben wir das Problem (Wortspiel beabsichtigt) gelöst, indem wir ein ereignisbasiertes, hochgradig autonomes jQuery-Plugin erstellt haben, das sich in eine maßgebliche Adress-API einklinkt. Wir nennen es liebevoll jQuery.liveaddress.

Sie können es in Aktion auf dieser LiveAddress-Dokumentationsseite sehen.

in-action

Tatsächliche Implementierungen sind auf ProCPR, Tortuga Rum Cakes und anderen Checkout-, Anmelde- und Kontaktformularen zu sehen. Die Endergebnisse lassen mich nach weiteren autonomen jQuery-Plugins suchen, die einfach funktionieren, ohne dass sie eingreifen oder konfiguriert werden müssen.

Ein autonomes Skript/eine autonome App/ein autonomes Plugin benötigt keine ständige Betreuung. Es tut seine eigenen Dinge, sendet aus, was es tut, und es *funktioniert einfach*. Hier werde ich mich kurz auf zwei Aspekte des autonomen Plugins konzentrieren

  • Plug-and-Play
  • Ereignisbasiert

Plug-and-Play

Im Gegensatz zu Webanwendungen müssen sich jQuery-Plugins an ihre Umgebung anpassen. Die Sizzle-Engine von jQuery nimmt viel Arbeit ab, aber in unserem Fall können Adressen nicht einfach „ausgewählt“ werden. Sie müssen *identifiziert* oder „zugeordnet“ werden.

Daher ist jQuery.liveaddress eher ungewöhnlich: Es ist nicht nur eine Funktion, die Sie direkt auf eine Menge übereinstimmender Elemente aufrufen können, noch unterstützt es Verkettung. Um wirklich Plug-and-Play zu sein, muss unser Plugin automatisch die Elemente in einem Formular finden, die sich auf Adressdaten beziehen: Straße, Stadt, Bundesland, Postleitzahl usw. Das Plugin scannt Ihre Seite nach solchen Elementen und ordnet sie automatisch in Adressstrukturen ein, die von Formular-Objekten verwaltet werden. Alles wird intern auf Änderungen überwacht. Wir nennen diesen Prozess „Auto-Mapping“.

Hier wurde unsere alte Javascript-Implementierung initialisiert. Sie hatte kein Auto-Mapping und war nicht sehr gut konstruiert

QadApi({
    timeout: 10,
    key: "HTML-KEY",
    busySubmit: false,
    autoClean: false,
    submitId: "submit",
    allowPost: false,
    properCase: true
    // ... other service-related configuration ...
  },
  {
    busyId: "QadBusy"
    // ... other CSS-related configuration ...
  },
  [
    {
      name: "Javascript Example",
      street: "street",
      city: "city",
      state: "state",
      zip: "zipcode"
    }
    // ... other addresses to be mapped, if any ...
  ]
);

Vergleichen Sie das mit jQuery.liveaddress, das Auto-Mapping durchführt

var liveaddress = $.LiveAddress("YOUR-API-KEY");

Sehen Sie den Unterschied?

Auf Webseiten mit klaren `name`- und `id`-Attributen für Eingabefelder, oder sogar `<label>-Tags und `placeholder`-Attributen, funktioniert das Auto-Mapping bemerkenswert gut. Sie würden nicht glauben, wie verschachtelt aussehende Formulare ich beim Testen gesehen habe, bei denen `name` und `id` nichts mit dem eigentlichen Feld zu tun hatten, und natürlich gab es keine `<label>-Tags. (Designer: beachten Sie das!) Für solche Fälle bieten wir eine Möglichkeit, Felder manuell zuzuordnen, entweder während der Initialisierung oder danach, unter Verwendung von Selektor-Strings

liveaddress.mapFields([{
  id: 'billing',                // IDs are not part of the address
  street: '#street1',
  street2: '#street2',
  city: '#city',
  state: '#state',
  zipcode: '#zip'
}]);

Denken Sie daran, wenn Ihr Plugin etwas automatisch tut oder annimmt, stellen Sie sicher, dass der Entwickler es überschreiben und die Kontrolle übernehmen kann.

Ein jQuery-Plugin sollte nicht wie Ihr Küchentisch von IKEA sein (erheblicher Montageaufwand erforderlich). Kann es nicht einfach sofort funktionieren? Was auch immer das für Ihr bestimmtes Skript bedeutet: Machen Sie es einfach nicht konfigurierbar, wenn möglich!

Ereignisbasiert

Betrachten Sie den wahrscheinlichen Fall, dass Sie mitten im Adressvalidierungsprozess eingreifen und etwas tun möchten. Wenn keine Ereignisse ausgelöst werden, woher wissen Sie, dass eine Adresse gerade validiert wurde? Sie müssten in den Quellcode des Skripts eintauchen und dort einen eigenen Hack einbauen. Ereignisse sind die elegante – und richtige – Lösung dafür.

Wir haben Glück, dass Javascript Ereignisse zu einer so routinemäßigen Sache macht! (Wortwörtlich.) Verwenden Sie Ereignisse. Feuern Sie sie ab, wenn coole (oder uncoole) Dinge passieren.

jQuery macht Ereignisse zum Kinderspiel und verwaltet sogar eine Referenz auf jeden gebundenen Handler. Während wir also alle daran gewöhnt sind, Ereignisse mit jQuery zu *binden*, vergessen Sie nicht, sie auch zu *auszulösen*

$(someElement).trigger(eventName, extraData);   // or use triggerHandler()

Stellen Sie beim Auslösen von Ereignissen sicher, dass Sie alle ereignisbezogenen Daten übergeben, damit der Handler den Zustand (Kontext) hat.

jQuery.liveaddress löst während seiner Laufzeit bis zu 14 benutzerdefinierte Ereignisse aus. Dies war immens nützlich und leistungsfähig, wie Sie unten sehen werden.

Tatsächlich bindet sich jQuery.liveaddress intern an seine eigenen Ereignisse. Das bedeutet, Sie haben die Möglichkeit, den Prozess jederzeit und unter jeder Bedingung zu stoppen. Zum Beispiel, um zu verhindern, dass der Benutzer eine Adresse übermittelt, der eine sekundäre (Wohnungs-)Nummer fehlt

liveaddress.on("AddressAccepted", function(event, data, previousHandler) {
  
  if (data.response.isMissingSecondary()) {

    data.address.abort(event);      // reset some things internally
    alert("Don't forget your apartment number!");
  
  } else {
                
    previousHandler(event, data);   // continue the process

  }

});

Beachten Sie, dass diese `on()`-Funktion auf dem liveaddress-Objekt aufgerufen wird und nicht auf dem üblichen `on()` von jQuery. Wenn Sie einen Handler mit `on()` von jQuery binden, wird dieser Handler nach den zuvor gebundenen ausgelöst. Da das Plugin zuerst an seine eigenen Ereignisse bindet und jeder Handler zum nächsten Ereignis weiterleitet, wird Ihr eigener Handler erst ausgelöst, wenn der gesamte Prozess abgeschlossen ist.

Um Abhilfe zu schaffen, entkoppelt die benutzerdefinierte `on()`-Funktion von jQuery.liveaddress die vorherigen Handler, legt Ihren darunter und pflanzt die anderen Handler darüber. Das bedeutet, dass Ihr Handler zuerst ausgelöst wird. Wie oben gezeigt, rufen Sie einfach den vorherigen Handler, der als Argument übergeben wird, auf, um den Validierungsprozess fortzusetzen. Wenn Sie das letzte Wort haben möchten, rufen Sie einfach den vorherigen Handler nicht auf.

6 Adressfelder 1 Adressfeld

Ein kurzer Einschub, bevor wir zum Ende kommen. Dies ist für die Designer.

Wie bereits erwähnt, sind Straßenadressen kompliziert. Sie erfordern 2 bis 6 Formularfelder, sie sind häufig in unterschiedlicher Reihenfolge angeordnet, jeder füllt sie anders aus und es gibt oft Fehler bei der Eingabe. Ja, die Überprüfung der Eingabe ist wichtig, aber darum geht es mir hier nicht. Haben Sie stattdessen darüber nachgedacht, alle Felder zu einem einzigen Feld zusammenzufassen?

Benutzer sind es gewohnt, eine Adresse in einem natürlichen oder intuitiven Format einzugeben, als ob sie sie auf einen Umschlag schreiben würden. Dies reduziert Eingabefehler und sorgt für eine angenehme Erfahrung.

Obwohl es Vorbehalte beim Parsen von Adresszeichenfolgen gibt, ist dies dennoch eine beträchtliche Verbesserung der Erfahrung Ihres Besuchers. Auf diese Weise können Benutzer eine frei formatierte Adresse eingeben und Sie können die einzelnen Komponenten bei Bedarf speichern.

Fazit

Wir haben uns ein paar verschiedene Wege angesehen, um Javascript nicht wie eine anspruchsvolle Freundin zu machen. In Kombination mit semantischem Markup können Skripte einfacher zu bedienen, intelligenter und intuitiver sein. Im Idealfall senden sie ihre Aktionen durch Auslösen von Ereignissen, damit anderer Code weiß, was vor sich geht und sich einklinken kann. Je automatisierter Ihr Skript ist, desto robuster muss es in feindlichen Umgebungen sein, wie z. B. Warenkorb-Checkout-Seiten oder Seiten mit hochdynamischen Inhalten und Funktionen. Autonome Skripte passen sich nach Möglichkeit an ihre Umstände an und scheitern, wenn sie es nicht können, auf würdevolle Weise.