Erstellen Sie ein In-Place-Bearbeitungssystem

Wenn Sie durch mehrere Seiten klicken, um ein Feld zu bearbeiten, klicken Sie auf "1999". In diesem Lernprogramm erfahren Sie, wie Sie ein In-Place-Bearbeitungssystem erstellen, das auf beliebten Websites wie Flickr zu finden ist.


Ein Wort vom Autor

Bei all dem Trubel um Web 2.0 ist die Benutzerfreundlichkeit heute viel wichtiger als je zuvor. Die Möglichkeit, Inhalte zu bearbeiten, ohne zu einer anderen Seite wechseln zu müssen, ist etwas, das sich viele Benutzer wirklich wünschen. Viele große Namen verwenden dieses Muster bereits mit großem Erfolg. Wenn Sie Flickr verwendet haben, haben Sie dies wahrscheinlich in Aktion gesehen.

Ich glaube, eine Demo sagt mehr als tausend Worte. Schlagen Sie die Demo an und probieren Sie es selbst aus.

Heute schauen wir uns an, wie wir dies mit unserer Lieblings-JavaScript-Bibliothek, jQuery, implementieren. Interessiert? Lass uns gleich loslegen!

Design-Ziele

Bevor wir uns mit der Implementierung der Funktionalität beschäftigen, werden hier einige Gedanken zu den Zielen und den daraus resultierenden Entscheidungen gemacht.

  • Wir müssen den Benutzer den Inhalt bearbeiten lassen, ohne die Seite zu verlassen. Dies ist eine Selbstverständlichkeit.
  • Dies sollte entweder als Ganzes funktionieren oder als Ganzes versagen. Wenn JS deaktiviert ist, möchten wir nicht auf seltsame Macken stoßen.
  • Der Benutzer sollte wissen, dass der Inhalt bearbeitet werden kann. Ein dezenter blauer Hintergrundwechsel sollte den Benutzer darauf aufmerksam machen.
  • Beim Auslösen des Editierens gibt es einige Optionen. Wir können den Benutzer entweder mit einem normalen Klick oder mit einem Doppelklick bearbeiten lassen. Ich habe Doppelklicks gewählt, da zufällige Doppelklicks mit einer geringeren Geschwindigkeit als zufällige Klicks auftreten. Beim Umschalten muss nur der Parameter im Bind-Ereignis geändert werden.
  • Eine Möglichkeit für den Benutzer, die Änderungen zu speichern oder zu verwerfen.
  • Das Speichern oder Bearbeiten von Ereignissen kann auf zwei Arten ausgelöst werden. Tastaturereignisse oder Mausereignisse. Ich habe Mausereignisse gewählt, da Tastaturereignisse nicht spezifisch sind.
  • In Bezug auf Mausereignisse können Sie entweder traditionelle Schaltflächen oder gewöhnliche Links verwenden. Ich habe Links ohne besonderen Grund gewählt.
  • Der Benutzer sollte die Bearbeitung fortsetzen können, auch wenn er außerhalb des Eingabefelds klickt oder die Seite verlässt und zurückkommt.
  • Darüber hinaus sollte der Benutzer in der Lage sein, so viele Felder wie möglich gleichzeitig zu bearbeiten.

Nun, da wir unsere Bedürfnisse festgelegt haben, können wir uns jetzt damit beschäftigen, wie wir dies tun werden.

Aktionsplan

Wir müssen jetzt herausfinden, was in einer bestimmten Reihenfolge getan werden muss.

Schritt 1: Wir müssen eine Klasse hinzufügen bearbeitbar zu jedem Element, das diese Funktionalität benötigt.

Schritt 2: Als nächstes müssen wir jedem bearbeitbaren Element Hover hinzufügen, um darauf aufmerksam zu machen, dass der Inhalt dieses Elements bearbeitbar ist. Wir fügen die Hover hinzu und entfernen sie mit JavaScript anstelle von CSS. Dies geschieht hauptsächlich für Geräte oder Browser mit deaktiviertem JavaScript. Wir möchten ihnen keine falschen visuellen Hinweise senden.

Schritt 3: Wenn ein bearbeitbares Element doppelt angeklickt wird, müssen wir den Inhalt austauschen und durch ein Textfeld mit dem alten Text ersetzen.

Schritt 4a: Wenn der Benutzer die Änderungen speichern möchte, kopieren Sie den Wert der Eingabe in das übergeordnete Element und entfernen Sie das Eingabefeld.

Schritt 4b: Wenn der Benutzer die Änderungen verwerfen möchte, ersetzen Sie den alten Inhalt und entfernen Sie das Eingabefeld.

Dies sind die grundlegenden Schritte zum Erstellen dieser Funktionalität. Natürlich gibt es wenige andere Kleinigkeiten, aber ich erkläre sie im weiteren Verlauf.

Core Markup

Das HTML-Markup der Demo-Seite sieht so aus.

    Direktes Bearbeitungssystem - von Siddharth für NetTuts      

Direktbearbeitung

von Siddharth für die lieben Leute von Net Tuts

Elemente mit einer Klasse von bearbeitbar sind gut editierbar. Falls Sie es nicht bemerkt haben, werden alle Elemente mit der bearbeitbar Klasse wird beim Schweben mit einem blauen Hintergrund angezeigt, um diese Fähigkeit anzuzeigen.

Doppelklicken Sie, um den Inhalt zu bearbeiten. Verwenden Sie die dynamisch erstellten Links, um die Änderungen zu speichern oder zu verwerfen. Sie können beliebig viele Felder zum Bearbeiten öffnen, ohne dass Sie Probleme haben müssen.

ich

  • bin Siddharth
  • liebe es mit dem web zu arbeiten
  • bin freelancer
  • Schreiben Sie für Net Tuts
  • finden Sie unter www.ssiddharth.com
  • werde dich nie im Stich lassen oder dich aufgeben :)

Dinge, die diese Woche zu tun ist

  • Lassen Sie sich von Deacon zur Designfreigabe
  • Senden Sie eine Rechnung an Albert
  • Beginnen Sie mit der Arbeit an Dwights Projekt
  • Sprich mit Sarah über neue Ideen
  • Überprüfen Sie die Website von Seth, um Fehler zu rendern
  • Treffen Sie sich mit Clintson, um das Projekt zu besprechen

Wenn Sie die Heizplatte außer Acht lassen, haben wir zwei ungeordnete Listen. Jeder li Element hat eine Klasse von bearbeitbar um anzuzeigen, dass der Inhalt bearbeitet werden kann.

Wir haben auch die jQuery-Bibliothek und unsere eigene Skriptdatei mitgeliefert.

CSS-Styling

 body Schriftfamilie: "Lucida Grande", "Verdana", serifenlos; Schriftgröße: 12px;  a color: # 000;  a: hover Textdekoration: keine;  p Marge: 30px 0 10px 0;  h1 font-size: 30px; Polsterung: 0; Marge: 0;  h2 font-size: 20px;  #container width: 820px; Rand links: auto; Rand rechts: auto; Auffüllen: 50px 0 0 0;  .editHover Hintergrundfarbe: # E8F3FF;  .editBox width: 326px; min-Höhe: 20px; Polsterung: 10px 15px; Hintergrundfarbe: #fff; Rand: 2px fest # E8F3FF;  ul list-style: none;  li Breite: 330px; min-Höhe: 20px; Polsterung: 10px 15px; Marge: 5px;  li.noPad padding: 0; Breite: 360px;  form width: 100%;  .btnSave, .btnCancel padding: 6px 30px 6px 75px;  .block float: left; Marge: 20px 0; 

Nichts Besonderes hier. Nur eine Menge Code für Layout und Styling.

Beachten Sie besonders die editHover und noPad Klassen. Wir werden sie ein bisschen verwenden.

JavaScript-Implementierung

Jetzt, da wir ein solides Framework und einige grundlegende Gestaltungsmöglichkeiten haben, können wir mit der Codierung der erforderlichen Funktionalität beginnen. Beachten Sie, dass wir jQuery umfassend einsetzen. Insbesondere benötigen wir mindestens Version 1.3 oder höher. Alles weniger und es wird nicht funktionieren.

Hovers hinzufügen

Wie bereits erwähnt, müssen wir bearbeitbaren Objekten einen dezenten blauen Hintergrund hinzufügen, um anzuzeigen, dass sie bearbeitbar sind. Wir haben bereits die erstellt editHover Klasse dafür zu sorgen.

 $ (". editable"). hover (Funktion () $ (this) .addClass ("editHover");, function () $ (this) .removeClass ("editHover"););

Dieser winzige Ausschnitt sorgt für uns. Wir verwenden jQuery's schweben Methode zum Hinzufügen der editHover Klasse, wenn das Element auf dem Bildschirm angezeigt wird, und entfernt es, wenn dies nicht der Fall ist. Wir gebrauchen diese um auf das bestimmte Element zu verweisen, über das Sie den Mauszeiger bewegen. Wenn wir gebraucht hätten .bearbeitbar stattdessen wird jedem Element die Klasse hinzugefügt. Also benutzen wir diese nur auf das Element zu zielen, das wir brauchen.

Elemente ausschalten

Zunächst müssen wir sicherstellen, dass unser Code ausgeführt wird, wenn das Zielelement doppelt angeklickt wird. Wir müssen also zuerst den Handler für dieses Ereignis anschließen.

 $ (". editable"). bind ("dblclick", replaceHTML);

Wir befestigen das replaceHTML Funktion zum Doppelklick Ereignis relativ zum bearbeitbar Element mit diesem einen Liner. Jetzt können wir die Elemente ausschalten.

 function replaceHTML () oldText = $ (this) .html () .replace (/ "/ g," ""); $ (this) .html ("") .html ("")
Änderungen speichern Änderungen verwerfen ");

Gehen wir unseren Code Stück für Stück durch.

Ich definiere die Funktionalität innerhalb einer separaten benannten Funktion anstelle einer anonymen Funktion aus einem bestimmten Grund: Ich werde diese Funktion mehr als einmal verwenden. Als Nächstes speichern wir den Inhalt des Elements für die zukünftige Verwendung mit jQuery html Methode und Ersetzen aller Anführungszeichen, da dies unsere Ausgabe auf der ganzen Linie durcheinander bringt.

Jetzt, da unsere Inhalte für eine spätere Verwendung sicher gespeichert sind, können wir die Elemente austauschen. Zuerst leeren wir das aus li Element durch Senden einer leeren Zeichenfolge an die html Methode. Als nächstes fügen wir etwas Standard-HTML für ein Eingabefeld ein. Wir fügen einige Klassen hinzu, um sie zu gestalten. Noch wichtiger ist, wir setzen es Wert Attribut für den ursprünglichen Text des Elements, das in gespeichert ist oldText. Wir haben auch ein paar Links hinzugefügt, um die Änderungen zu speichern und zu verwerfen. Wir haben auch Klassen hinzugefügt, so dass sie leicht und für das Styling anvisiert werden können.

Wie immer verwenden wir diese um auf das Element zu zielen, das das Ereignis ausgelöst hat.

Die Änderungen behalten

 $ (". btnSave"). live ("click", function () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g , "" "); $ (this) .parent () .html (newText););

Lassen Sie mich zunächst jQuery's vorstellen Leben Methode. Sie haben wahrscheinlich noch nicht so viel gesehen, deshalb werde ich eine kurze Einführung geben.

Sie können Handler nicht mit Ereignissen verbinden, die von Elementen ausgelöst werden, die nicht einmal im DOM vorhanden sind, wenn die Seite und das JavaScript geladen wurden. Wenn Sie normale Ereignisbindungsfunktionen verwenden, schlägt dies aus dem oben genannten Grund fehl. Das Leben Die Methode kümmert sich darum.

Es bindet Handler an Ereignisse, unabhängig davon, wann das Element erstellt wurde. Weitere Informationen hierzu finden Sie in den offiziellen Dokumenten.

Schauen wir uns jetzt unseren Code an. Wir binden zunächst den in unserer anonymen Funktion enthaltenen Code an die klicken Veranstaltung. Innerhalb der Funktion speichern wir zunächst den im Eingabefeld enthaltenen Text. Dies kann etwas schwierig sein, da das Eingabefeld keine ID hat. Also suchen wir zuerst nach dem Formularelement, das zufällig sein Geschwister ist, und durchlaufen dann das Eingabeelement. Wir kopieren dann seinen Wert, nachdem wir alle Anführungszeichen ersetzt haben.

Als Nächstes erhalten wir das übergeordnete Verknüpfungselement, das li Element und ersetzen Sie den HTML-Inhalt durch den Text, den wir im vorherigen Schritt kopiert haben.

Dieser Block hätte leicht als One-Liner erstellt werden können, aber ich habe ihn aus Gründen der Lesbarkeit auf zwei Zeilen aufgeteilt.

Die Änderungen werden verworfen

 $ (". btnDiscard"). live ("click", function () $ (this) .parent () .html (oldText););

Das ist so einfach wie es aussieht. Da möchte der Benutzer keine der Änderungen behalten. Wir ersetzen einfach den HTML-Inhalt des übergeordneten Elements durch den ursprünglichen Text, den wir zuvor in das kopiert hatten oldText Variable.

Damit ist der Kern unserer Arbeit erledigt. Wir müssen nur ein paar Änderungen vornehmen, um sicherzustellen, dass die Dinge nicht beschädigt werden, wenn der Benutzer unerwartete Dinge tut.

Binden und lösen

Wenn Sie unseren Code zu diesem Zeitpunkt ausprobiert haben, werden Sie wahrscheinlich mit dieser Funktionalität brechen: Wenn ein Benutzer in das resultierende Eingabefeld doppelklickt, wird jetzt der HTML-Inhalt des Bearbeitungssystems gefüllt. Versuch es selber. Bei jedem Doppelklick wird der Wert des Eingabefelds reflektiert, indem ein weiterer Satz Text hinzugefügt wird. Dieses Problem wird wahrscheinlich viel schlimmer sein, wenn Sie als Auslöseereignis click gewählt haben.

Um dies zu korrigieren, müssen Sie den Ereignishandler für dieses bestimmte Element allein aufheben und erneut binden, sobald der Benutzer entweder auf "Speichern" oder "Verwerfen" klickt. Lassen Sie uns das jetzt umsetzen.

Unsere vorherigen Codeblöcke müssen jetzt so bearbeitet werden:

 function replaceHTML () // Code $ (this) .html ("") // Code zum Einfügen früherer Formulare .unbind ('dblclick', replaceHTML); 

Wir haken den Handler für das Element aus, das das Ereignis ausgelöst hat. Der Rest der Elemente mit der bearbeitbar Die Klasse hat noch immer ihre Handler und reagiert auf Ereignisse.

 $ (". btnSave"). live ("click", function () // Früherer Code $ (this) .parent () .html (newText) .bind ("dblclick", replaceHTML););
 $ (". btnDiscard"). live ("click", function () $ (this) .parent () .html (oldText) .bind ("dblclick", replaceHTML););

Als Nächstes fügen wir diese Handler wieder hinzu, unabhängig davon, ob der Benutzer sie bearbeiten möchte oder nicht. Wenn wir diese nicht erneut anhängen, können die Felder nur einmal bearbeitet werden. Beim zweiten Doppelklick werden die Handler nicht mehr an die Ereignisse angehängt. Wir korrigieren dies, indem wir die Handler mit den Ereignissen verbinden.

Einige Tweaks

Dieser letzte Code dient lediglich dazu, das Erscheinungsbild unseres Effekts zu verbessern. Wenn Sie bemerkt haben, das li hat ein wenig Polsterung, damit der Text besser aussieht. Wenn der Text jedoch entfernt wird und durch ein Textfeld ersetzt wird, sieht das Ergebnis unschön aus und bricht den Effekt. Wir möchten, dass das Textfeld genau den Platz einnimmt, den der ursprüngliche Text benötigt hat. In diesem Sinne fügen wir ein noPad Klasse zu dem Element, wenn es doppelt angeklickt und wieder entfernt wurde, wenn der Benutzer die Bearbeitung speichert oder verwirft.

 function replaceHTML () // Code $ (this) .addClass ("noPad") .html ("") // Früherer Code

Wir haken den Handler für das Element aus, das das Ereignis ausgelöst hat. Der Rest der Elemente mit der bearbeitbar Die Klasse hat noch immer ihre Handler und reagiert auf Ereignisse.

 $ (". btnSave"). live ("click", function () // Früherer Code $ (this) .parent () .removeClass ("noPad") // Früherer Code);
 $ (". btnDiscard"). live ("click", function () $ (this) .parent () .removeClass ("noPad") // Früherer Code);

Der vollständige Code

So sieht der vollständige Code aus:

 $ (document) .ready (function () var oldText, newText; $ (". editable"). hover (function () $ (this) .addClass ("editHover");, function () $ ( this) .removeClass ("editHover");); $ (". editable"). bind ("dblclick", replaceHTML); $ (". btnSave"). live ("click", function () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g," ""); $ (this) .parent () .html (newText). removeClass ("noPad") .bind ("dblclick", replaceHTML);); $ (". btnDiscard"). live ("click", function () $ (this) .parent () .html (oldText) .removeClass ("noPad") .bind ("dblclick", replaceHTML);); Funktion replaceHTML () oldText = $ (this) .html () .replace (/ "/ g," ""); $ ( this) .addClass ("noPad") .html ("") .html ("
Änderungen speichern .unbind ('dblclick', replaceHTML); );

Nicht schlecht. Fünfzig ungerade Zeilen, um neue Funktionen hinzuzufügen.

Noch einen Schritt weiter: Das Backend

Im Interesse, es nicht zu lange zu machen, habe ich die Client-Funktionalität allein erstellt. Wenn Sie diese Funktionalität in Ihren eigenen Projekten implementieren möchten, wurde implizit davon ausgegangen, dass Sie ein Back-End-System zum Speichern dieser Änderungen benötigen. Vor allem benötigen Sie eine AJAX-Anforderung, um diesen Aufruf asynchron durchzuführen.

Das Hinzufügen dieser Funktion sollte ein Kinderspiel sein, aber notieren Sie sich dies. Der obige Code wurde nur zur Veranschaulichung dieses Musters und nicht zur Verwendung in der Produktion erstellt. Daher habe ich mich darauf verzichtet, zusätzliche IDs-Attribute zu Elementen und Namensattribute zu Textfeldern hinzuzufügen. Fügen Sie in Ihrem Produktionscode alle hinzu, damit das Namensattribut des Textfelds sinnvoll festgelegt werden kann. Auf diese Weise kann das Back-End erkennen, welche Daten aktualisiert werden müssen.

Um eine AJAX-Anfrage hinzuzufügen, muss unser Save-Handler folgendermaßen aktualisiert werden:

 $ (". btnSave"). live ("click", function () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g , "" "); $ .ajax (type:" POST ", URL:" handler.php ", data: newText, success: function (msg) // Code, der eine erfolgreiche Bearbeitung widerspiegelt;) $ (this) .parent () .html (newText) .removeClass ("noPad") .bind ("dblclick", replaceHTML););

Denken Sie daran, dass das Backend alle Informationen, die Sie an es senden, verstehen kann. Sie benötigen zusätzlich zum aktualisierten Text einige zusätzliche Daten, damit die App weiß, welche Daten bearbeitet werden sollen. Sie können problemlos mehrere Daten in das Skript einsenden, wenn Sie dies benötigen.

Fazit

Und dort hast du es; So fügen Sie Ihren Projekten eine benutzerfreundliche Funktion hinzu. Hoffentlich fanden Sie dieses Tutorial interessant und dies war für Sie nützlich. Fühlen Sie sich frei, diesen Code an anderen Stellen in Ihren Projekten wiederzuverwenden, und klingeln Sie hier, wenn Sie in Schwierigkeiten geraten.

Fragen? Schöne Dinge zu sagen? Kritikpunkte Schlagen Sie den Kommentarbereich an und hinterlassen Sie einen Kommentar. Glückliche Kodierung!

  • Folgen Sie uns auf Twitter oder abonnieren Sie den Nettuts + RSS-Feed für mehr tägliche Webentwicklungsberichte und -artikel.