Ich habe ein Shadowbox-Skript. Wenn ich die Seite lade funktioniert alles gut, aber wenn ich diese jquery load Funktion aufrufen und dann versuchen die Shadowbox durch Klicken auf das Bild auszulösen, öffnet sich stattdessen das große Bild in einem neuen Fenster. Hier ist der Code:
%Vor%Irgendeine Idee, warum das passiert?
BEARBEITEN
Also, wir endlich bekommen den Grund dafür. 15 Stunden nach dem ersten Kommentar zu diesem Problem und mindestens 50 Iterationen später haben wir das Problem erkannt und behoben.
Es ist mir plötzlich aufgefallen, als ich local aaa.html
und bbb.html
auf meinem Server erstellt habe. Das war, als es mich traf, dass die Elementknoten für den Inhalt, der ersetzt wurde, vollständig aus dem DOM entfernt wurde, wenn $.load()
die Callback-Funktion ausführt. Sobald die Inhaltselemente #menu-home
ersetzt wurden, wurden sie aus dem DOM entfernt und Shadowbox wurde nicht mehr angewendet.
Nachdem ich das herausgefunden hatte, war es nur eine Frage einer einzigen Websuche und ich fand:
Nabble-Shadowbox - Shadowbox reinitialisieren
Insbesondere die Antwort von mjijackson . Was er beschreibt, ist, wie man Shadowbox mit:
neu startet (reinitialisiert) %Vor% Sobald der Inhalt von #menu-home
neu geladen wurde, muss der Shadowbox-Cache gelöscht werden (im Wesentlichen durch Herunterfahren auf der Seite), dann wird Shadowbox.setup()
ausgeführt, wodurch alle Elemente erkannt werden erneut. Sie führen die Methode Shadowbox.init()
auch nicht erneut aus.
Ich habe bemerkt, dass Sie versucht haben, die Shadowbox.setup()
nach der $.load()
zu kopieren, zumindest sequentiell im Code. Dies würde jedoch nicht funktionieren, da das Cache-Clearing zuerst durchgeführt werden muss, und in erster Linie, weil die Funktionen .clearCache()
und .setup()
nach dem % $.load()
ausgeführt werden müssen (beendet und führt alle Rückrufe durch). Diese beiden Funktionen müssen im Callback-Handler $.load()
ausgeführt werden. Sonst läuft es sofort, aber $.load()
ist asynchron und wird zu einem späteren Zeitpunkt abgeschlossen.
Ich werde einige andere Änderungen, die ich gemacht habe, durchgehen, nur damit Sie verstehen, was, warum und warum.
Hinweis: Ich bin mir nicht sicher, ob Sie mit <base>
vertraut sind, aber das Folgende steht ganz oben im Element HEAD
:
Damit kann ich nur die Ressourcendateien auf Ihrem Computer verwenden. Sie werden dies wahrscheinlich nicht mehr auf Ihrer tatsächlichen Website verwenden wollen. Stellen Sie beim Kopieren / Einfügen sicher, und entfernen Sie diese Zeile.
%Vor% Hier sehen Sie, dass ich eine relative URL im Attribut HREF
und einen Link zu einigen Seiten auf meinem Server habe. Der Grund für die Links zu meinem Server ist, dass ich aufgrund von Cross-Site-Scripting-Einschränkungen nicht auf Ihre aaa.html
- und bbb.html
-Dateien über AJAX zugreifen konnte. Die Links zu meiner Website sollten ebenfalls entfernt werden.
Nun, der Grund, warum ich das rel
-Attribut hier verwende, ist, dass ich zulassen will, dass die Links über das href
-Attribut weiterarbeiten, falls JS nicht korrekt funktioniert oder es etwas anderes gibt Error. Wenn Sie separate Dateien haben, eine für vollständiges HTML-Dokument und eine andere für nur die Fragmente, sollten Sie dies tun. Wenn Sie sowohl das vollständige Dokument als auch den Inhalt nur aus der verknüpften Datei bereitstellen können, benötigen Sie wahrscheinlich nicht das rel
-Attribut, aber Sie müssen die Anforderung verwalten, damit der Server weiß, wie er reagieren soll (vollständiges Dokument) oder nur der Inhaltsteil).
Ich habe hier nur einen zentralen Ort für die Initialisierungs- / Setup-Anfragen erstellt. Ziemliech direkt. Beachten Sie, dass ich die Eigenschaft Shadowbox.initialized
hinzugefügt habe, damit ich verfolgen kann, ob Shadowbox.init()
ausgeführt wurde, was nur einmal ausgeführt werden kann. Es ist jedoch eine gute Idee, wenn alles möglich ist.
Ich habe auch eine variable Funktion erstellt, die entweder als reguläre Funktion aufgerufen werden kann:
%Vor%Oder als Funktionsreferenz:
%Vor% Sie werden wahrscheinlich feststellen, dass ich die $()
entfernt und stattdessen durch jQuery()
ersetzt habe. Dies kann zu einem wahren Albtraum werden, wenn Sie mit einer Umgebung mit mehreren Frameworks und Bibliotheken konfrontiert werden, die um $()
konkurrieren, also vermeiden Sie es am besten. Das hat mich neulich echt gut gebissen.
Da wir einen Closing-Bereich innerhalb des .ready()
-Rückrufs haben, können wir dies nutzen, um mehrere "private" Variablen zu speichern, die zu verschiedenen Zeiten bei der Ausführung des Skripts verwendet werden.
Beachten Sie ,
am Ende aller außer der letzten Zeile. Sehen Sie, wie ich das $
"importiert" habe, indem ich es der jQuery-Variablen gleich gemacht habe, was bedeutet, dass Sie es tatsächlich in diesem # verwenden könnten.
Dies wird ausgeführt, wenn $.load()
den Prozess der AJAX-Anfrage beendet. Beachten Sie, dass der in der Anfrage zurückgegebene Inhalt bereits zum Zeitpunkt der Ausführung im DOM platziert wurde. Beachten Sie auch, dass wir den tatsächlich zwischengespeicherten Inhalt in $content.data()
speichern, der niemals von der Seite entfernt werden sollte. nur der Inhalt darunter.
cacheContent()
ist eine Methode, die Sie nicht wollen; im Wesentlichen, wenn es bereits bei einer vorherigen Anfrage geladen wurde, wird es zwischengespeichert und dann direkt abgerufen, anstatt ein weiteres $.load()
zu initiieren, um den Inhalt vom Server zu holen. Sie möchten das vielleicht nicht tun; Wenn ja, kommentieren Sie einfach den zweiten Block if
in der Funktion menuLoadContent()
aus.
Was dies tut, ist zunächst das $content
-Element seiner Inhalte / Elemente zu leeren und dann das angegebene zeichenkettenbasierte Markup, das wir zuvor gespeichert haben, hinzuzufügen, indem wir das $content.html()
erhalten. Dies werden wir hinzufügen, wenn es möglich ist; Sie können sehen, sobald die verschiedenen Links angeklickt und geladen wurden. Wenn dieselbe Anforderung wie aktuell geladen ist, wird auch der Code vollständig ausgeführt.
(Wir verwenden $content
like, weil es sich um eine Referenz auf eine Variable handelt, die ein jQuery-Element enthält. Ich mache das, weil es sich in einem Closure-Bereich befindet, was bedeutet, dass es nicht im globalen Gültigkeitsbereich angezeigt wird für Dinge wie Event-Handler verfügbar sein.
Suchen Sie nach den Inline-Kommentaren im Code.
%Vor% Nun wähle ich die relevanten Menüpunkte anders aus. Sie benötigen keine separate $.click()
-Deklaration für jedes Element. Stattdessen wähle ich #menu a[rel]
, was jedes a
Element im Menü mit rel="not empty rel attribute"
enthält. Beachten Sie, dass ich hier menuLoadContent
als Funktionsreferenz verwende.
Dann, ganz unten, starte ich die boxInitialize();
, um Shadowbox einzurichten.
Lass es mich wissen, wenn du Fragen hast.
Ich denke, ich könnte dem auf den Grund gehen. Ich denke, der Fehler ist die Art und Weise, wie Sie den $.load()
des neuen Inhalts bearbeiten, wenn Sie auf einen Menüeintrag klicken, zusammen mit einer nicht abgefangenen Ausnahme, die ich mit iframe
zu tun hatte:
Nicht erfasste Ausnahme: Unbekannter Player iframe
Dieser Nabble-Shadowbox-Forenthread befasst sich damit Error. Ich bekomme das eigentlich nicht mehr, aber ich denke, es kam darauf, dass ich auf den Menüpunkt tour
geklickt habe.
Nun, was Sie tun, um den Inhalt für die Menüpunkte zu laden, macht wirklich keinen Sinn. Sie fordern ein vollständiges HTML-Dokument an und wählen dann nur ein Element mit class="content"
aus. Der einzige Vorteil, den ich daraus ziehen kann, ist, dass die Seite nie neu geladen wird, aber Sie müssen eine andere Methode wählen, um die Daten zu erhalten und anzuzeigen, die nicht die gesamte Seite über AJAX herunterladen und dann versuchen, jQuery zu parsen nur den Teil, den du willst.
Ich glaube, dass die Handhabung des Inhalts, der auf diese Weise geladen wird, die Ursache Ihres Problems ist. Daher macht das Umschalten von Menüansichten $.load()
Ihre Seite auf unerwartete Weise kaputt.
Frage: Warum verlinken Sie nicht einfach auf die eigentliche Seite und überspringen Sie alle $.load()
-Fantasie? In Bezug auf die Geschwindigkeit wird es, wenn überhaupt, keine so großen Auswirkungen haben. Es macht einfach keinen Sinn, AJAX so zu verwenden, wenn man sie einfach mit demselben Inhalt verknüpfen könnte.
Es gibt zwei Alternativen, mit denen Sie das erneute Laden von Roundtrip-Seiten verhindern können:
Richten Sie Ihre AJAX-Aufrufe so ein, dass nur der .content
-Anteil des Markups angefordert wird, wenn Sie in der URL das Flag ?contentonly=true
haben, nicht das gesamte HTML-Dokument. So wird es traditionell gemacht und ist normalerweise relativ einfach, wenn Sie eine Skriptumgebung haben.
Dann antwortet Ihr Server nur mit der angeforderten Inhaltsansicht.
Stellen Sie alle Inhaltsansichten innerhalb desselben HTML-Dokuments bereit und zeigen Sie sie entsprechend an:
%Vor%Es sieht nicht so aus, als hätten Sie eine ganze Menge Inhalt, so dass die anfängliche Seitenladung wahrscheinlich nicht so viel Einfluss auf diesen speziellen Ansatz haben wird. Sie müssen sich vielleicht überlegen, wie Sie Bilder vorab laden, aber das ist eine sehr bekannte Technik mit vielen Qualitätsskripten und Tutorials da draußen.
Jede dieser Techniken könnte die #!
(hashbang) -Technik verwenden, um Inhalte zu laden, obwohl ich glaube, dass es bei Suchmaschinen Probleme gibt. Hier ist jedoch ein Link zu einer einfachen Technik, die ich vor einiger Zeit zusammengestellt habe:
Auch dies ist nur ein Tipp, aber beziehen Sie sich nicht auf Ihr "content" -Element mit einem class
, dh .content
. Es sollte nur ein Inhaltsanzeigeelement im Markup vorhanden sein, richtig? Es gibt nicht mehr als eins? Verwende ein id="content"
; Das sind die ID
Attribute, um ein einzelnes Element zu referenzieren. class
es sollen Elemente nach einem Merkmal gruppieren, das sie teilen, also wenn ich .hide()
die Inline-Inhaltsansichten (siehe # 2) suche, suche ich nach allen class="content-view"
-Elementen, die alle ähnlich sind (sie enthalten Inhaltsansichts-Markup). Die Variable $content
sollte sich jedoch auf $('#content');
beziehen. Dies beschreibt, was die Elemente sind.
Das hat für uns funktioniert, wir haben eine Site erstellt, die vertikale Tabs verwendet und die Seiten mit unseren Shadowbox-Images mit jQuery.load
aufgerufen hatGeben Sie einfach allen Anchor-Tags die Klasse="sbox" und fügen Sie dieses Skript in die Kopfzeile ein.
%Vor%Hinweis: Wir mussten die .sbox-Klasse auf alle unsere Anker sowie auf den Anker für die Registerkarte mit dem Namen .load
setzenDanke an diesen Kerl- & gt; Ссылка
Nun, basierend auf Shems Antwort ist das meine Lösung. Jeder Klick auf bestimmte Klasse, Setup und Öffnen Shadowbox mit Elementen aus derselben Klasse:
%Vor%Danke an alle
Tags und Links javascript jquery shadowbox