Wir bauen eine Drupal-Site mit einem Audio-Player, der weiterspielen soll, während Sie auf der Seite surfen (so etwas wie Soundcloud).
Momentan laden wir die Seiten von <a>
mit ajax und injizieren das HTML in die Seite und verwenden history.js, um den Ort zu manipulieren.
Es gibt jedoch einen großen Nachteil:
Da eine neu geladene Seite unterschiedliche css und js haben kann, müssen wir die aktuellen Skript-, Stil- und Linkelemente mit dem Ajax-Antworttext (hässlicher Regex) vergleichen und nur die neuen, noch nicht existierenden Elemente hinzufügen. 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).
Die Verwendung eines iframe kann dieses und andere Probleme lösen:
Wenn Sie zum ersten Mal auf einen Link auf der Website klicken, wird der Seiteninhalt durch einen iframe ersetzt, der 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 hätte, dass ich das denke: Ich denke, die Verwendung eines iFrames 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 einwandfrei, außer in iOS. Iframes sind buggy wie die Hölle. Dennoch denke ich, wir gehen mit der iframe-Lösung.
Ich würde sagen ... halte es einfach, dumm. Gehen Sie für die iframe-Lösung, ich weiß, dass es einen Teil Ihrer Seele tötet, aber es ist die einfachste Lösung für Ihr Problem und stellt die geringste Veränderung in die Zukunft Probleme zu lösen.
KISS.
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.
Früher waren die Iframes schlecht für SEO, aber heutzutage können Webcrawler normalerweise zwischen Ihrer Website und iframes-Inhalten wechseln.
Die Verwendung von iframe wird für Sie einfacher und einfacher, anstatt "hässlicher Regex" zu verwenden. Warum behalte es nicht einfach, oder? KISS-Prinzip
Du könntest ein paar komische Sachen machen.
Erstens könnten Sie window
object mit einem neuen vergleichen und alle zusätzlichen Eigenschaften entfernen ( hier ist ein Beispiel ). Dasselbe könnte getan werden, do document
, HTMLElement
, Array.prototype
Objekte und andere, die möglicherweise über Skripte erweitert werden. Auf diese Weise würden Sie viel von den definierten Sachen beseitigen, und Garbage Collector würde das irgendwann fallen lassen.
Zweitens möchten Sie alle Ereignislistener entfernen. Dies ist möglich, indem addEventListener
usw. neu definiert wird ( beziehen Sie sich auf diese Frage zum Beispiel ).
Drittens sollten Sie Intervalle und Zeitüberschreitungen nicht vergessen, die mit dem gleichen Ansatz wie zuvor behandelt werden können (wrapping setTimeout
etc) ( hier gefunden ).
Natürlich würde es eine Menge Zeug geben, 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 Titeln möglich). Sehen? Eine Menge Arbeit zu tun, und das kann nichts geben. Nach all diesen Theorien würde ich iframe verwenden. Weil, wisst ihr, Beispiel: Wenn einige Skripte eurer Site eine JS-Funktion umschließen (wie wir es an zweiter und dritter Stelle machen), dann würde das Ajaxing die Wrapping-Aufrufe dieser Funktion überlagern, was wirklich schlimm ist.
Wie Sie gesagt haben,
Die Verwendung eines iframe kann dieses und andere Probleme lösen: Wenn Sie zum ersten Mal auf einen Link auf der Site klicken, wird der Seiteninhalt durch einen Iframe ersetzt, der 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 etwas Ähnliches mit Ajax machen. 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.
Ich möchte Ihnen ein paar Fragen stellen und diese Antwort bearbeiten, wenn Sie antworten, wenn es Ihnen nichts ausmacht. Der Grund dafür ist meiner Meinung nach, dass Sie beim Start dieses Projekts einige unbequeme Architekturentscheidungen getroffen haben. 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 Back-End aufteilen und Ihr Front-End in Modelle, Ansichten und Controller aufteilen, nicht unbedingt mit Frame-Arbeiten, oder indem Sie dies tun (oder MVVM, wie eckig es tut) Einige schnelle Empfehlungen Wie Sie die Daten laden, injizieren Sie nicht direkt html, verwenden Sie Ihre Backend-Technologie, um JSON oder XML an das Frontend zu senden, und parsen Sie das, um Ihren HTML-Code in einer Vorlage anzuzeigen, die sich auf Frontend befindet , 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 Manipulator-Methoden über eine einfache API auf, so dass sie sauberer ist und schneller und zuverlässiger arbeitet. Wenn Sie mobile native Apps erstellen, verwenden Sie Ihre API-Ebene einfach erneut.
Vergleiche von regulären Ausdrücken auf css und js klingen wie ein kompletter schlechter Hack, ich stimme zu, es wäre besser, iframes zu verwenden, aber ich brauche noch ein paar mehr Informationen, um das gesamte Setup zu besprechen und Ihnen hoffentlich weiter zu helfen Perspektive.
UPDATE:
Ich verstehe, warum die Seiten möglicherweise unterschiedliche CSS haben, aber ich nehme an, dass Ihr Musikplayer js dieselbe Quelle sein sollte, an die verschiedene Medien-IDs angehängt sind. 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 Ihrer Drupal-Front-End-Vorlage, in der 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 integriertem JS, und lassen Sie die ID von der DB zum Front-End über eine PHP-Variable übergeben, wie PHP-Rendering Server-Seite passiert, wenn DOM geladen wird Zusammen mit Ihrem JS sind die Seiten-IDs vorhanden. Hoffe, das hilft, lassen Sie es mich wissen, wenn Sie weitere Fragen haben.
Tags und Links jquery ajax iframe drupal html5-history