2016-02-02 2 views
9

Wir bauen eine Drupal-Site mit einem Audio-Player, der weiterspielen soll, während Sie auf der Seite surfen (so etwas wie Soundcloud).Sollte ich einen Iframe anstelle von Ajax verwenden?

Zur Zeit laden wir geklickt <a> Websites mit AJAX und injizieren Sie die HTML in die Seite und verwenden Sie history.js, um den Speicherort zu manipulieren.

Es gibt einen großen Nachteil aber:

Da eine neu geladene Seite kann unterschiedliche css und js drauf, haben wir die aktuellen Skript, Stil und Verbindungselemente auf den Ajax-Antworttext (hässlich regex) vergleichen und fügen nur die neuen, noch nicht vorhandenen Elemente hinzu. Auf diese Weise wird das Laden einer anderen Seite nicht gelöscht/entfernt/rückgängig gemacht, sobald die Skripte ausgeführt wurden. Dies kann zu einem Leistungsproblem werden (während Regex gegen Markup sowieso ist).

ein iframe verwenden, kann diese und andere Probleme lösen:

Wenn Sie zuerst einen Link auf der Website klicken, wird der Seiteninhalt durch einen iframe ersetzt wird, die nur die Seite lädt. Der Audio-Player befindet sich im ursprünglichen Dom, d. e. außerhalb des iFrames. Das Klicken auf Links innerhalb des Iframes kann abgefangen und auch in der History-API verwendet werden.

Also, obwohl ich nie gedacht habe, dass ich denke: Ich denke, mit einem iframe könnte hier die bessere Option sein, nicht wahr?

PS: Mein Hauptproblem ist, dass ich nicht kontrollieren kann, dass verschiedene Seiten auf der Website verschiedene Skripte haben, die Stile sind wirklich kein Problem. Wenn es nur eine riesige statische js und css Website-weit gab, hatte ich kein Problem.

aktualisieren

Die Iframe-Lösung funktioniert gut, außer in iOS. Iframes sind buggy wie die Hölle. Dennoch denke ich, dass wir mit der iframe-Lösung gehen werden.

+0

Sie könnten eine "reset.css" -Datei haben, die alle zuvor geladenen css aufräumt - aber dann müssten Sie genau wissen, was jede Seite in der Art von css anwenden würde, was wie Sie klingt habe keine Kontrolle über. Es ist auch möglich, css zu entladen, wenn es über 'link's geladen wird, aber auch hier hängt es davon ab, wie Sie das css laden, schauen Sie hier: http://stackoverflow.com/questions/1598899/unload-css-from-webpage –

+0

Das CSS ist kein Problem. Wenn Sie Stil- oder Verknüpfungselemente entfernen, wird die CSS rückgängig gemacht. Wenn Sie die neuen anhängen, werden die Stile aktualisiert. aber Skripte verhalten sich anders – Alex

+0

Warum brauchen Sie verschiedene CSS/JS-Dateien? Kannst du sie nicht verketten/minimieren und einmal servieren? Auf diese Weise müssen Sie beim Ändern der Seite nur die verschiedenen Zustände (Ereignisse binden, losbinden ...) korrekt behandeln. –

Antwort

3

Ich würde sagen ... behalte es einfach, dumm. Gehen Sie für die iframe-Lösung, ich weiß, es tötet einen Teil Ihrer Seele, aber es ist die einfachste Lösung für Ihr Problem und stellt die geringste Veränderung der in Probleme in der Zukunft.

KISS.

+0

Wir testen derzeit die iFrame-Methode und ihre wunderschöne. Der einzige wirkliche Nachteil ist iOS, es hat riesige Probleme mit iframes und auch Bugs :( – Alex

0

Sie könnten versuchen, einige seltsame Sachen zu tun.

Zuerst können Sie window Objekt mit frischen vergleichen und alle zusätzlichen Eigenschaften (here's an example) entfernen. Die gleiche Sache könnte gemacht werden tun document, HTMLElement, Array.prototype Objekte und andere, die möglicherweise über Skripte erweitert werden. Auf diese Weise würden Sie viel von dem definierten Zeug beseitigen, und der Müllsammler würde das irgendwann fallen lassen.

Zweitens möchten Sie alle Ereignislistener entfernen. Dies ist möglich, indem addEventListener usw. (refer to this question for example) neu definiert wird.

Drittens sollten Sie Intervalle und Timeouts nicht vergessen, die mit dem gleichen Ansatz wie zuvor behandelt werden können (Umbruch setTimeout usw.) (found it here).

Natürlich gäbe es eine Menge Zeug, abhängig davon, welche Skripte auf der Seite laufen. Sie können also eine Seite aktualisieren, wenn der Benutzer auf einen Link klickt, während ein Titel nicht abgespielt wird (Übergang zwischen den Titeln möglicherweise). Sehen? Eine Menge Arbeit zu tun, und das kann nichts geben. Nach all diesen Theorien würde ich iframe verwenden. Weil, wie Sie wissen, Beispiel: Wenn einige Skripte Ihrer Site eine JS-Funktion umschließen (wie wir es in der zweiten und dritten Spalte machen), würde das Ajaxing die Wrapping-Aufrufe dieser Funktion überlagern, was wirklich schlimm ist.

+0

All dies macht auch Spaß, Lösungen wie diese sind sehr komplex und werden zweifellos in der Zukunft Probleme verursachen. Während sie sind Instanzen, dass dies das Risiko wert ist ... In diesem Fall gibt es eine Lösung, die viel einfacher ist. –

+0

@FlipVernooij Was genau ist, rate ich von einer solchen Vorgehensweise in der Antwort ab. –

2

Ich sehe keinen Grund, warum Sie iframe nicht verwenden sollten. Ich denke, iframe zum Einbetten von Seiten in Ihre Website ist in Ordnung. Dafür ist ein Iframe zuständig.

Die iframes waren schlecht für SEO, aber heute können Web-Crawler in der Regel zwischen Ihrer Website und iframes Inhalt reisen.

Die Verwendung von iframe wird einfacher und einfacher für Sie anstelle von "hässlicher Regex". Warum behalte es nicht einfach, oder? KISS principle

+0

Wenn es Ihr Ziel ist, eine einzelne Inhaltsregion zu behalten, dann wird das funktionieren. – CoveGeek

+0

Wir testen derzeit die iframe-Methode und es ist wunderschön Nachteil ist iOS, es hat riesige Probleme mit iframes und auch Bugs. Ich glaube nicht, dass SEO ein Problem sein wird, da der iframe nur generiert wird, wenn Sie auf einen Link klicken (via JS). – Alex

-1

Ich möchte Ihnen ein paar Fragen stellen und bearbeiten Sie diese Antwort, wie Sie reagieren, wenn es Ihnen nichts ausmacht. Der Grund dafür ist, glaube ich, dass Sie einige unbequeme Architekturentscheidungen getroffen haben, als Sie dieses Projekt starteten. Aus Ihrer Beschreibung entnehme ich, dass Sie statische HTML-Seiten laden, wenn auf Tags geklickt wird, wenn nicht, was ist Ihre Backend-Technologie?

Sie sollten die Logik idealerweise in Front- und Backend trennen und Ihr Frontend in Modelle, Ansichten und Controller trennen, nicht unbedingt durch Frameworks, oder indem Sie dies tun (oder MVVM, wie eckig) Empfehlungen darüber, wie Sie die Daten laden, injizieren Sie nicht HTML direkt, verwenden Sie Ihre Back-End-Tech, um JSON oder Xml an Front-End zu senden, und parsen, um Ihre HTML anzuzeigen, auf einer Vorlage, die auf Frontend, anstatt Ihre dom runter, was unnötig langsam und teuer sein wird. Wenn Sie ein Back-End haben, versuchen Sie, Ihre Persistance-Schicht in einer Black-Box-Umgebung zu erstellen, und rufen Sie die Manipulatormethoden über eine einfache API auf, so dass sie viel sauberer ist und schneller und zuverlässiger arbeitet. Wenn Sie mobile native Apps erstellen, verwenden Sie Ihre API-Ebene einfach erneut.

Regelmäßige Ausdruck Vergleiche auf CSS und JS klingt wie eine völlig schlechte hack, ich stimme zu, es wäre besser, Iframes zu verwenden, aber wieder brauche ich ein wenig mehr Informationen zu Ihrem gesamten Setup zu diskutieren und Ihnen hoffentlich helfen breitere Perspektive.

UPDATE:

Ich verstehe, warum die Seiten unterschiedliche CSS haben können, aber ich nehme an, Ihre Musik-Player js die gleiche Quelle mit verschiedenen Medien-IDs sollten mit ihnen verbunden. Ausgehend von dieser Konfiguration, in Ihrer drupal-Datenbank, die ich als MySql anwende, erstellen Sie eine eigene Tabelle für Ihre "music player" -Seiten, neben dem Standard-ID-Indexeintrag sowie created_at, modified_at usw., ein Feld für Ihre spielbaren Quellen.

Schreiben Sie diese Quell-ID in Ihre Drupal Frontend-Vorlage, wo Sie den tatsächlichen Player erstellen, aus Ihrer Datenbank. Auf diese Weise haben Sie eine Seite für Ihre Musikseiten. Für CSS halten Sie alles in einer Datei, vielleicht verwenden Sie etwas wie SASS oder weniger, um Ihre CSS-Datei zu kompilieren, um alles in mehr Ordnung zu halten.

In einem Gist, haben Sie Ihre drupal Seite, PHP schreiben Sie Ihre HTML-Seite mit eingebetteten JS, und lassen Sie die ID von der DB zum Front-End über eine PHP-Variable übergeben, wie PHP-Rendering Serverseite passiert, wenn DOM ist zusammen mit Ihrem JS geladen, werden die Seiten-IDs angezeigt. Hoffe, das hilft, lassen Sie mich wissen, wenn Sie weitere Fragen haben.

+0

Danke für Ihre Eingabe, aber ich nicht ganz bekommen was Sie versuchen zu sagen. Selbst wenn ich Backbone oder eckig verwenden würde, würde ich immer noch das Problem der seitenabhängigen Skripte und Stile haben. Was genau sind Ihre Fragen? :) temporäre upvote <3 – Alex

+0

Hey danke, na und? Ich fragte, war Ihr Backend, dh wo js und css laufen, auf einem einfachen Apache/nginx/jetty was auch immer Webserver oder begleitet mit einer Backend-Sprache wie PHP, Java oder Nodejs, entsprechend würde ich vorschlagen, organisieren Ihre con Zeltzuteilung Teil in einer besseren Weise, so dass Sie nicht auf Probleme stoßen, wo Sie nur mit iframes stecken bleiben. – serdarsenay

+0

Wie ich geschrieben habe, verwenden wir Drupal, also PHP. Dennoch verhindert die Sprache nicht mein Problem, dass verschiedene Seiten unterschiedliche Skripte haben können. – Alex

-1

Wie Sie sagten,

einen Iframe verwenden dieses und andere Probleme lösen können: Wenn Sie zuerst einen Link auf der Website klicken, wird der Seiteninhalt durch einen iframe ersetzt, die nur die Seite lädt. Der Audio-Player befindet sich im ursprünglichen Dom, d. e. außerhalb des iFrames.Das Klicken auf Links innerhalb des Iframes kann abgefangen und auch in der History-API verwendet werden.

Sie können eine ähnliche Sache mit Ajax tun. Legen Sie den gesamten Inhalt, der ersetzt werden soll, in einen Container und ersetzen Sie den Inhalt des Containers anhand der Ajax-Antwort. Berühren Sie nicht den Inhalt außerhalb dieses Containers. Ich denke, das wird auch Ihr Leistungsproblem lösen.

+0

"Da eine neu geladene Seite unterschiedliche css und js haben kann, müssen wir die aktuellen Skript-, Stil- und Link-Elemente mit dem Ajax-Antworttext (hässlicher Regex) vergleichen und nur die neuen, noch nicht existierenden Elemente hinzufügen Wenn Sie eine andere Seite laden, wird das Löschen/Entfernen/Rückgängigmachen einmal ausgeführter Skripte nicht ausgeführt. Dies kann zu einem Leistungsproblem führen (obwohl Regex gegen Markup sowieso ist). " – Alex

+0

Aber das wäre dann vorzuziehen, ganze Seite mit CSS- und JS-Elementen in iframe selbst zu laden. –

+0

Ich glaube, Sie haben kein Problem verstanden. Das Laden der Inhalte über AJAX ist keine große Sache, aber was ist mit JS und CSS? Bitte lies meine Frage nochmals sorgfältig durch. – Alex

Verwandte Themen