Wie implementiert Twitter seine Tweet Box?

8

Ich versuche, etwas wie Tweets Twitter-Box zu implementieren, insbesondere:

  • Markiert automatisch Text in einem roten Hintergrund, wenn die Gesamtlänge 140 Zeichen überschreitet.
  • Markiert automatisch Links, Erwähnungen und Hashtags in Blau.

Dies sollte automatisch geschehen, wenn ein Benutzer tippt.

Durch das semantische Markup, das ich auf Twitter sehe, sieht es so aus, als würden sie ein contentEditable div verwenden. Und das DOM-Inside wird geändert, sobald eine Erwähnung / Hashtag / Link erkannt wird oder wenn die Länge über 140 Zeichen überschritten wird:

%Vor%

Was ich bisher gemacht habe

Momentan verwende ich ein contentEditable-Feld. Es löst eine Funktion onChange/onInput aus, die den Text analysiert. Überprüfe, ob es einen Benutzernamen / Link / Hashtag über regexr hat und ersetze sie durch die entsprechenden Tags (ich verwende nur ein einfaches <i> -Tag, um Nutzername und Hashtag vorerst einzuschließen). Das Problem, das ich habe, ist, dass, weil ich das DOM von contentEditable ändert / modifiziere, die Position des Cursor-Cursors verloren geht. Ich schaute auf diesen Thread Persisting die Änderungen von Bereichsobjekten nach Auswahl in HTML und es funktioniert nur gut, wenn das DOM nicht geändert wird (was es in meinem Fall ist, umgebende Tags / Hashtags mit <i> -Tags, Links mit <a> -Tags und Überlauf) mit <b> -Tags.

Geige: Ссылка

Hat jemand alternative Lösungen / Ansätze zur Lösung dieses Problems? Vielleicht sollte ich contentEditable nicht benutzen? Oder eine Art, die das DOM des Feldes contentEditable nicht direkt verändert, so dass die Caret-Position beibehalten wird? Jede Hilfe wäre willkommen! Ich habe versucht, mit window.getSelection() herumzuspielen und es vor der Änderung des DOM zu speichern, aber es scheint immer wieder zurückgesetzt zu werden, nachdem DOM-Änderungen angewendet wurden.

    
trekforever 02.03.2015, 22:02
quelle

3 Antworten

3

Dies ist keine direkte Antwort mit Quellcode, der den Teil Ihrer Anwendung zu Ihrer Spezifikation macht.

Dies ist wirklich nicht einfach was zu tun ist.

Sie haben recht - der Weg zur Lösung dieses Problems besteht in der Verwendung eines contenteditable="true" Containers. Aber ich fürchte, dass es von dort viel viel komplizierter wird.

Enter DraftJS - Eine JavaScript-Lösung für die Rich-Text-Bearbeitung, die die meisten schweren Aufgaben für Sie erledigt.

Beide meiner Lösungen erfordern die Verwendung von React und DraftJS

Die Plug & Play-Lösung:

Die Reagieren + DraftJS + Die "Plugin" -Lösung von Someone Else ist bereits hier. Sie können draft-js-plugins.com herunterladen. Und hier ist der Github-Quellcode .

Ich persönlich würde diesen Weg nicht gehen. Ich würde lieber ihren GitHub Quellcode studieren und meinen eigenen DraftJS entities implementieren . Weil ich denke, dass sich React-JS-Plugins für Links und Erwähnungen ein wenig klobig und übergewichtig anfühlt. Und wo "erwähnst" du? Ihre eigene Anwendung? Twitter? Auf diese Weise haben Sie die Kontrolle darüber, wo Sie die so genannten "Erwähnungen" finden.

Die DIY-Lösung:

Der beste Weg, den ich gefunden habe, ist, ein eigenes Set von funktionierenden entities zu erstellen. oben auf einem DraftJS-basierten Rich-Text-Editor.

Dies erfordert natürlich auch, dass Sie Reagieren verwenden.

Verzeihen Sie, dass ich nicht wirklich einen vollständigen Arbeitscode erstellt habe. Ich wollte etwas Ähnliches für eine App machen, die ich in Meteor mit React am Frontend erstelle. Das machte für mich wirklich Sinn, weil ich nur eine weitere Bibliothek (DraftJS) hinzufügen würde und der Rest wäre meine Gewohnheit entities codiert.

    
Jeremy Iglehart 28.08.2016 04:10
quelle
2

Was ich getan habe, ist eine Art Hack, funktioniert aber als Workaround-Lösung.

Ich habe ein einfaches Textfeld (nicht zufrieden stellend wegen dem, was als nächstes kommt, werde ich weiter unten erklären) und ein Div, das absolut hinter dem Textfeld positioniert ist. Unter Verwendung von Javascript kopiere ich den Inhalt aus dem Textbereich in das div, indem ich ihn in 140 Zeichen zerlege und alle zusätzlichen Zeichen in ein <em /> -Tag lege.

Nun, es ist etwas komplizierter, weil der Twitter-Algorithmus zur Berechnung einer Tweet-Länge anders ist (Links zählen nicht als ihr tatsächlicher Wert, weil t.co URL verkürzt wird). Die genaue Methode kann im offiziellen twitter / twitter-txt-Repository gefunden werden.

Schritt-für-Schritt-Code.

Wickle ein einfaches Textfeld in ein div, um die CSS zu vereinfachen:

%Vor%

CSS erstellt nur den Textbereich und das Div direkt übereinander und markiert den Text.

%Vor%

Jetzt ist der spaßige Teil, dies wird mit jQuery implementiert, aber das ist nicht das Wichtigste.

%Vor%

Fügen Sie einen Event-Handler bei der Änderung hinzu, und das allgemeine Dokument ist fertig und Sie sind fertig. Sehen Sie sich den folgenden Code-Link an.

Beachten Sie, dass das dahinter liegende div auch beim Laden der Seite mit js erstellt werden kann:

%Vor%

Vollständiges Beispiel

Siehe Arbeitsbeispiel hier: Ссылка

    
Hussard 24.01.2017 19:48
quelle
1

Stellt sich heraus, das ist wirklich nicht eine einfache Sache zu tun. Ich habe in den letzten paar Tagen damit zu kämpfen, und ich bin nicht sehr nah an einer Lösung.

Ihre beste Drop-In-Lösung ist derzeit die At.js-Bibliothek , die immer noch gepflegt wird, aber definitiv nicht nicht perfekt. Eines der Beispiele zeigt, wie Sie Art einen Text markieren können.

Der nervigste Teil dieses Problems ist, dass Twitter eine schöne Lösung hat, die scheinbar perfekt funktioniert und uns direkt ins Gesicht starrt. Ich habe einige Zeit damit verbracht, herauszufinden, wie sie ihre "Tweet-Box" implementieren, und das ist definitiv nicht trivial. Es sieht so aus, als würden sie fast alles manuell machen, einschließlich der Emulation von Undo / Redo-Funktionalität, Abfangen von Copy / Pasten, Bereitstellung von benutzerdefiniertem Code für IE / W3C, benutzerdefinierter Programmierung von Mac / PC und vielem mehr. Sie verwenden ein contenteditable div, das an und für sich problematisch aufgrund von Unterschieden in Browserimplementierungen ist. Es ist eigentlich ziemlich beeindruckend.

Hier ist der relevanteste (verschleierte, leider) Code, der aus der Boot-JavaScript-Datei von Twitter stammt (gefunden durch die Überprüfung der Kopfzeile der eingeloggten Twitter-Homepage). Ich wollte den Link nicht direkt kopieren und einfügen, falls er für meinen Twitter-Account personalisiert ist.

%Vor%

Offensichtlich löst diese "Antwort" nichts, aber hoffentlich könnte sie genug bieten, um eine Diskussion über dieses Thema (wieder) zu entfachen.

    
Aaron 09.06.2015 21:27
quelle