Funktions-Verlust beim Umhängen der Iconbar (neue Profilseite)

14.06.2014 21:18
#1 Funktions-Verlust beim Umhängen der Iconbar (neue Profilseite)
avatar
Mitglied

Hallo,

im Zusammenhang mit dem neuen Profil-Update und dem ColorPicker ist mir aufgefallen, dass Events für Elemente in der Iconbar unter Umständen nicht mehr auslösen.

Beim ersten Aufruf eines Tabs (z.B. Nachricht senden) funktioniert noch alles wie gewünscht, die Iconbar wurde neu geladen und alles darin korrekt initialisiert. Wechselt man danach jedoch in einen anderen Tab (Gästebuch), funktionieren einige Elemente nicht mehr. Aufgefallen ist mir das als erstes am gerade aktualisierten Colorpicker. Ich habe danach mal Ursachenforschung betrieben und auch festgestellt, dass dieses Problem wohl bei allen Elementen auftritt, welche ihre Events nachträglich per JavaScript eingehängt bekommen. Und gerade bei jQuery ist es durchaus üblich, nach dem ready-Event den Elementen weitere Handler für click etc. mitzugeben.

Als Problemstelle vermute ich stark die Funktion iconbarSwitch. Meiner Meinung nach wird da nur der HTML-Code der bestehenden Iconbar zwischengespeichert, aus dem alten Container entfernt und in den neuen Container im aktiven Tab wieder eingefügt. Dafür sprechen die Felder der Farbvorschau und der zuletzt gewählten Farbe beim ColorPicker, welche ihren letzten Zustand (zu sehen an der Hintergrundfarbe der DIVs) beibehalten.

Dieses Verhalten ist aber auch bei offiziellen jQuery-Plugins zu beobachten. Letztlich funktionieren eben nur solche Events, welche direkt in HTML-Tags als Attribute reingeschrieben wurden, da diese durch das Kopieren des reinen Quelltextes erhalten bleiben. Alle per JavaScript eingehängten Events, nicht in Attributen vergebene data-Werte und andere wechselnde Zustände (aktivierte Checkboxen) gehen komplett verloren.


Letztlich müssten also nur die bereits bestehende Symbolbar im DOM umgehängt und nicht die verlustbehaftete Quelltext-Kopie neu eingefügt werden. Wenn ich mich noch recht erinnere, machen dies jQuery-Funktionen wie z.B. append(…) bereits automatisch. Ist ein Element bereits auf der Seite eingebunden, wird es nicht dupliziert sondern einfach nur umgehängt.


Viele Grüße

Florian


 Antworten

 Beitrag melden
14.06.2014 22:47
#2 RE: Funktions-Verlust beim Umhängen der Iconbar (neue Profilseite)
avatar
Techniker

Die Iconbar wurde dafür konzipiert nur einmal auf einer Seite zu existieren und dort mit einem Textfeld zu interagieren. Die neue Profilseite vereint aber weitere Seiten in einer, welche über Javascript gewechselt werden. Aus diesem Grund muss bei einem Tab-Switch die Iconbar immer komplett neu auf das aktuelle Textfeld initialisiert werden.

Prinzipiell sollten Events wie z.B. ein onclick oder onchange von dem Element direkt ausgelöst werden. Der Grund dafür ist recht simpel. Ein externes Anmelden eines Events durch z.B. $(SELECTOR).click(function ... ) kann man immer nur dann machen, wenn man absolut sicher ist, dass dieses Element da Existiert. In der Regel also eigentlich nur bei eigenen Elementen. Die Iconbar ist allerdings ein sozusagen "externes" Element (aus deiner Sicht) und somit nie sicher hinsichtlich der Verfügbarkeit.
Aus diesem Grund sollten Events immer vom Element selber durch ein z.B. onclick="meinefunction()" ausgelöst werden.
Das gleiche gilt auch für andere Elemente bei denen du dir nicht absolut sicher sein kannst.

Es ist btw. auch viel übersichtlicher, wenn man direkt am Element sieht, dass es dieses und jenes Event wirft und man nicht erst den Quelltext durchsuchen muss. Macht man z.B. auch in AngularJS.

Unabhängig davon werde ich nächste Woche mal schauen, in wie weit man das eventuell schöner lösen kann.


 Antworten

 Beitrag melden
15.06.2014 01:11
#3 RE: Funktions-Verlust beim Umhängen der Iconbar (neue Profilseite)
avatar
Mitglied

Besten Dank für die schnelle Antwort!

Das Mitnehmen der bestehenden Iconbar finde ich eigentlich sogar ganz gut. Leider findet weder eine Neuinitialisierung statt noch werden alle notwendigen Eigenschaften auf den neuen Tab transferiert. Das ist eben ein Problem welches auftritt, sobald etwas per .html(…) verschoben werden soll.

Ich habe jetzt spontan nicht das passende Template-Element gefunden, wenn ich aber die Funktion iconbarSwitch (über die Konsole) austausche, bleibt die komplette Funktionalität der Iconbar erhalten:

1
2
3
4
5
 
var iconbarSwitch = function(targetTextarea) {
$('#'+targetTextarea+'_iconbar').append($('.iconbarContainer').find('.iconbarcontent'));
miranus_iconbar_textarea.length = 0;
miranus_add_iconbar_textarea(targetTextarea);
};
 


Das genügt erstmal den aktuellen Anforderungen, die ohnehin nur einmalig vorhandene Iconbar umzuhängen.

Das externe Anmelden der Events sehe ich hier nicht als allzu großes Problem. Glücklicherweise können neue Handler für das ready-Event beliebig auf einer Seite verteilt werden. Dadurch lassen sich Events auch nur dann einhängen, wenn das entsprechende Element in der Symbolbar geladen wurde. Der Vorteil ist, dass auch nicht ganz so technik-affine Nutzer einfach einen einzigen HTML-Baustein in die Symbolbar kopieren können.

Attribute wie onclick haben natürlich schon ihre Existenz-Berechtigung, füllen den HTML-Code aber genauso häufig auch auf. Skript und HTML werden so oft zu sehr ineinander vermischt, der HTML-Code kann dadurch gerne mal schnell sehr unübersichtlich werden.

Weitere Probleme ergeben sich, wenn die Nutzer ein beliebiges offizielles jQuery-Plugin einbinden wollen. Oft wird dort nur ein DIV durch etwas komplett neues ersetzt. Egal ob Color-, DatePicker oder sonst irgendwas. Die Initialisierung erfolgt einmalig zu Anfang, beim Kopieren des reinen HTML wird entweder nur das ursprügnliche DIV oder ein nicht mehr funktionales Konstrukt übernommen. Diese Plugins bieten sich vor allem dadurch an, dass jQuery standardmäßig in den Foren zur Verfügung steht. Evtl. könnte man noch mit delegierten Events etwas erreichen, aber wer kann oder möchte schon ein bestehendes Plugin mühsam umschreiben.


 Antworten

 Beitrag melden
15.06.2014 10:27
#4 RE: Funktions-Verlust beim Umhängen der Iconbar (neue Profilseite)
avatar
Techniker

Prinzipiell hast du damit recht, dass man es aktuell entsprechend so anpassen kann, sodass es in diesem Fall funktioniert und da bin ich bereit auch mal zu schauen (wie bereits geschrieben)

Allerdings sind deine Annahmen leider etwas falsch und so nicht richtig. Wie bereits geschrieben, kannst du das externe Anmelden von Events vornehmen, wenn du genau weist was passiert bzw. genommen wird und auch in Zukunft genommen wird! Sprich eigentlich wenn du deine eigene Seite komplett selber gemacht hast. Dann ist so was absolut kein Problem. Nur bist du bei den Foren hier nicht der alleinige Entwickler der die Seite gebaut hat und bist darauf angewiesen was wir hier machen. Sprich du kannst nur versuchen dich mit "deinem" Code da "reinzuhängen", was auch vollkommen OK ist. Nur musst du bei solch einem Vorgehen anders handeln.
Es gibt nicht nur JQuery, sondern auch einen Haufen weiterer sehr guter JS-Libs bzw. Frameworks (z.B. AngularJS, BackboneJS, EXTjs usw.) und es ist nicht garantiert, dass wir nicht in naher Zukunft weitere mit verwenden und da funktioniert deine Herangehensweise einfach so nicht.
Auch wenn du von "offiziellen" JQuery Plugins sprichst, ist das dennoch reichlich egal. Diese Plugins sind dafür gebaut einen zu unterstützen, sind aber keinen Garant das diese so wie erwartet überall zu funktionieren haben und müssen.
Kleines Beispiel ... Wir verwenden auf einer Seite JQuery, JQuery-UI und AngularJS nach angular-seed Richtlinie
Jetzt wollen wir ein Draggable-Div haben .... laut jquery-ui doc müssten wir lediglich ein $(selector). draggable(); ... gut das wäre in diesem Fall falsch.
Richtige Herangehensweise wäre, dass wir in angular dafür eine Direktive schreiben und das JQuery-UI-Plugin wrappen und dann dem Element geben was draggable sein soll.
Das ist nur ein kleines Beispiel.

Es spricht auch absolut nichts gegen die Verwendung der Event-Tags, solange dort "nur" ein Funktionsaufruf stattfindet. Dann ist diese Verwendung dieser Event-Tags auch vollkommen richtig und führt keineswegs zur Vermischung von JS und HTML (sprich Unübersichtlichkeit)

Schlussendlich zum Punkt "nicht Technikaffin". Wir sind natürlich stets bemüht dem User es so einfach und verständlich wie möglich zu machen, was wir mit der Iconbar z.B. auch beweisen.
Neue Smilies usw. kann der Nutzer ohne große Kenntnisse selber einfügen (was auch sicher und garantiert funktioniert). Fängt der Nutzer jetzt an aber komplette Scripte mit einzubauen (was ja möglich ist), gehen wir ab diesen Punkt davon aus, dass der Nutzer genau weis was diese machen und wie diese funktionieren.
Scripte sind komplex und können auch sehr viel kaputt machen oder gefährliche Dinge tuen (das könnte z.B. ein schöner ColorPicker sein in dem ich eine Funktion versteckt habe, die die Cookies des Nutzers ausliest und die Logindaten des Forums stiehlt). Wenn der Nutzer unwissend ist und einfach per Copy&Paste das bei sich einbinden ist er auch komplett selber daran schuld Punkt! Genau so sieht es natürlich mit der Funktionalität bzw. Funktionsweise aus.


 Antworten

 Beitrag melden
17.06.2014 22:22
#5 RE: Funktions-Verlust beim Umhängen der Iconbar (neue Profilseite)
avatar
Mitglied

Meine Annahme rührte daher, dass ein Skript gleich mit dem Element in der Symbolbar geladen wird und alles dafür Nötige dann somit zur Verfügung steht. Bei anderen Bibliotheken mag das sich evtl. tatsächlich anders verhalten, aber AngularJS werde ich mir sowieso bei Gelegenheit mal genauer vornehmen.


Allerdings glaube ich dann trotzdem noch nicht, dass $('selektor') .html(…) in der Funktion iconbarSwitch eine wirklich passendere Lösung darstellt. Versteh mich nicht falsch, die Übernahme der Symbolbar finde ich soweit gut, nur werden mit dieser Funktion leider nicht alle Eigenschaften der umgehängten Elemente übernommen. Deshalb dürfen meiner Meinung nach ohne eine mögliche Neuinitialisierung keine Informationen beim Umhängen der Symbolbar verloren gehen.

Deswegen war mein Vorschlag, diese verlustbehaftetet Funktion durch eine andere wie $('containerNeu') .append(…) oder eine ähnliche auszutauschen, welche dann auch konsequent die komplette Symbolbar überträgt. Ich sage auch bewusst Vorschlag, da mein geposteter Code nur eine funktionierende Möglichkeit darstellt, ich wollte die jetzt keineswegs zwanghaft durchsetzen. Mir ist klar, dass alle Änderungen genau überprüft werden müssen, bevor sie endgültig sind. Hatte aber gehofft, zumindest das Problem dadurch etwas deutlicher machen zu können.

Ein mit anderen Bibliotheken kompatibles Skript ist es natürlich dadurch nicht geworden, weil in den Foren bisher immer nur jQuery eingesetzt wurde. Eure speziellen Zukunftspläne kenne ich natürlich nicht (Weltherrschaft? ;), deswegen können wir als Nutzer natürlich immer nur die aktuelle Lage beurteilen. Aber letztlich ist die aktuelle Implementation von iconbarSwitch ja auch noch auf jQuery aufgebaut. Wenn die Methode .append(…) mal nicht mehr benutzt werden kann, wird an entsprechender Stelle .html(…) wohl auch nicht mehr benötigt.


Zitat
Schlussendlich zum Punkt "nicht Technikaffin". Wir sind natürlich stets bemüht dem User es so einfach und verständlich wie möglich zu machen, was wir mit der Iconbar z.B. auch beweisen.

[…] gehen wir ab diesen Punkt davon aus, dass der Nutzer genau weis was diese machen und wie diese funktionieren.


Schön gesagt, da kann ich dir ja nur recht geben. Die Iconbar finde ich tatsächlich sehr gelungen und die eingebauten Skripte zu kennen ist auch immer gut. Copy&Paste ist aber glaube dennoch ein auch hier weit verbreitetes Phänomen. Ziemlich interessant ist doch zu sehen, wie viele Nutzer sich auf einmal melden, wenn ein Skript nicht mehr funktioniert. Vor lauter Copy von den verschiedensten Orten wussten viele überhaupt nicht, an wen sie sich wenden könnten. Zum Glück gibt es noch einige aufmerksame User, die sofort richtig geschaltet haben … Klar, ist nicht eure Aufgabe, aber habt ihr bestimmt auch schon festgestellt. Ist ja aber auch nur verständlich, die Anpassbarkeit ist eben ein großes Plus, das mag einfach jeder.


Wenn sich bei Xobor die Voraussetzungen ändern, werde ich natürlich das Bestmögliche versuchen, die Skripte dementsprechend passend zu erstellen, welche Bibliotheken/Frameworks auch immer das dann sein werden. Aber ich hoffe, ich konnte damit nochmal genauer aufzeigen, welches allgemeine Problem ich hier überhaupt beim verlustbehafteten Kopieren sehe.

Dann warte ich jetzt einfach nur noch gespannt auf das Resultat deiner Begutachtung.


P.S.: Nicht eilig, aber ist die Funktion iconbarSwitch überhaupt über ein Template zu erreichen? Konnte die jetzt nirgendwo entdecken, evtl. weil das Profil noch so neu ist und noch nicht zur Verfügung steht …
Hat mich eben nur gewundert.


 Antworten

 Beitrag melden
17.06.2014 23:38
#6 RE: Funktions-Verlust beim Umhängen der Iconbar (neue Profilseite)
avatar
Techniker

es gab heute ein Update und wir hängen die jetzt mit append um ;)

Zur Funktion.
Nein die habe ich nur in das Template geschrieben, da es dort die einzige Stelle in unseren Templates ist, die aktuell 2 Iconbars auf mehreren Textareas auf ein und der selben Seite hat.

ps.
wenn du dir Angular anschaust, dann schau dir gleich den Seed dazu an ^^ (nur so am Rande)
https://github.com/angular/angular-seed


 Antworten

 Beitrag melden
17.06.2014 23:44 (zuletzt bearbeitet: 17.06.2014 23:45)
#7 RE: Funktions-Verlust beim Umhängen der Iconbar (neue Profilseite)
avatar
Mitglied

Yaaay! Damit hatte ich heute Abend noch nicht gerechnet.

Dankeschön, sowohl für deine Mühe, das Update und natürlich auch den Tipp!


 Antworten

 Beitrag melden
Bereits Mitglied?
Jetzt anmelden!
Mitglied werden?
Jetzt registrieren!