Die unmögliche Inline Javascript Verzögerung / Schlaf

8

Es gibt eine JavaScript-Funktion, von der ich keine Kontrolle über den Code habe, der eine von mir geschriebene Funktion aufruft. Meine Funktion verwendet DOM, um einen iFrame zu generieren, definiert src und hängt ihn dann an ein anderes DOM-Element an. Bevor meine Funktion jedoch zurückkehrt und die fortlaufende Ausführung der enthaltenden Funktion erlaubt, muss der iFrame unbedingt vollständig geladen sein.

Hier sind die Dinge, die ich versucht habe und warum sie nicht funktionieren:

1. Die SetTimeout-Option:
99,999% der Zeit ist dies die Antwort. Tatsächlich habe ich in den vergangenen zehn Jahren, in denen ich JavaScript betreut habe, immer darauf bestanden, dass Code jederzeit umgestaltet werden kann, um diese Option zu nutzen, und niemals glaubte, dass ein Szenario existierte, wo das nicht der Fall war. Nun, ich habe endlich eins gefunden! Das Problem ist, dass, weil meine Funktion inline aufgerufen wird, wenn die nächste Zeile ausgeführt wird, bevor mein iFrame geladen wird, mein Skript vollständig gekeult wird und das Skript von dem Moment an ausgeführt wird, in dem mein Skript beendet wird. Ein Rückruf von Arten funktioniert nicht

2. Die "Do Nothing" -Schleife:
Diese Option, die Sie verwenden, während (// iFrame nicht geladen ist) {// do nothing}. In der Theorie würde dies nicht zurückkehren, bis der Rahmen geladen ist. Das Problem besteht darin, dass der iFrame nie geladen wird, da dies alle Ressourcen belegt. Dieser Trick, obwohl schrecklich unprofessionell, schmutzig etc. funktioniert, wenn Sie nur eine Inline-Verzögerung benötigen, aber da ich einen externen Thread benötige, wird es nicht funktionieren.
In FF, nach ein paar Sekunden, pausiert es das Skript und Es wird eine Warnung angezeigt, die besagt, dass ein nicht reagierendes Skript vorhanden ist. Während dieser Alarm ausgelöst wird, kann der iFrame geladen werden, und dann kann meine Funktion zurückkehren, aber wenn der Browser 10 Sekunden lang eingefroren ist und der Benutzer dann einen Fehler korrekt abweisen muss, ist dies ein Nein.

3. Der Modelldialog:
Ich wurde von der Tatsache inspiriert, dass das FF-Popup den iFrame laden ließ, während die Ausführung der Funktion angehalten wurde. Als ich darüber nachdachte, erkannte ich, dass der modale Dialog die Ausführung unterbricht und gleichzeitig andere Threads weiterlaufen lässt ! Brilliant, also entschied ich mich, andere modale Optionen auszuprobieren. Dinge wie alert () funktionieren wunderbar! Wenn es auftaucht, auch wenn es nur für eine Zehntelsekunde hoch ist, kann der iFrame abgeschlossen werden, und alles funktioniert großartig. Und nur für den Fall, dass die 1/10 Sekunde nicht ausreicht, kann ich den Modell-Dialog in die While-Schleife von Lösung 2 einfügen, und es würde sicherstellen, dass der iFrame rechtzeitig geladen wird. Süße, oder? Abgesehen von der Tatsache, dass ich jetzt einen sehr unprofessionellen Dialog für den Benutzer öffnen muss, um mein Skript zu starten. Ich habe mit mir über dieses Kosten / Nutzen dieser Aktion gekämpft, aber dann bin ich auf ein Szenario gestoßen, wo mein Code 10 Mal auf einer einzigen Seite aufgerufen wurde! 10 Benachrichtigungen vor der Bearbeitung einer Seite ablehnen ?! Das erinnert mich an die Script-Kiddie-Seiten der späten 90er und ist KEINE Option.

4. Ein gaaillion anderes Delay-Script da draußen:
Es gibt ungefähr 10 jQuery-Delay- oder Sleep-Funktionen, von denen einige eigentlich ziemlich clever entwickelt sind, aber keine funktionierten. Ein paar Prototypen-Optionen, und wieder, konnte niemand es gefunden! Ein Dutzend anderer Bibliotheken und Frameworks behaupteten, sie hätten das, was ich brauchte, aber leider haben sich alle verschworen, um mir falsche Hoffnung zu geben.

Ich bin davon überzeugt, dass, da ein eingebauter Modelldialog die Ausführung anhalten kann, während andere Threads fortgesetzt werden können, es einen Code geben muss, der zugänglich ist, um dasselbe ohne Benutzereingaben zu machen.

Der Code ist buchstäblich Tausende und Abertausende von Zeilen und ist proprietär, also schrieb ich dieses kleine Beispiel für das Problem, mit dem Sie arbeiten sollten. Es ist wichtig zu beachten, dass der ONLY-Code, den Sie ändern können, in der Funktion onlyThingYouCanChange

enthalten ist

Testdatei:

%Vor%

blank_frame.html:

%Vor%

HIER IST DIE ANTWORT, DIE ICH AUS KOMBINIERTEN IDEEN VON RESPONDERN GEMACHT HABE! SIE GUYS ROCK! neue Quelle der Funktion, die ich ändern durfte: %Vor%

slow_page.php:

%Vor%

Ich möchte darauf hinweisen, dass ich festgestellt habe, dass es nichts außerhalb dieser Funktion gibt, das ich ändern könnte, und das Hinzufügen der PHP-Seite hat diese "Regel" verletzt, aber in einigen Fällen war ich dazu in der Lage. Wenn ich das nicht könnte, könnte blank_frame.html anstelle von slow_page.php aufgerufen haben und hätte es nur einmal aufrufen müssen (also zweimal pro Frame), vorausgesetzt, dass Es reagierte in der gleichen Zeit wie die iFrame-Last. Wenn die iFrame-Last aus irgendeinem Grund langsamer war, könnte sie 2ce (insgesamt 3 Aufrufe an den Server) genannt werden.

    
trex005 01.01.2011, 23:57
quelle

8 Antworten

1

NB Das ist extrem hacky und ich würde es in keiner realen Situation verwenden. Unter anderen möglichen Problemen könnten Sie sich bei ausreichendem Traffic selbst DDOS machen.

Sie können die Schlaffunktionalität durch Ausführen von nicht asynchronen (A) JAX-Aufrufen erstellen. In einigen älteren Browsern kann dies alles einfrieren, aber es wird zumindest keine Benutzerreaktion erforderlich sein.

%Vor%     
lonesomeday 02.01.2011, 00:17
quelle
3

Ja, die Tatsache, dass JavaScript single threaded ist, beißt dich wirklich hier her. Sie können einen synchronen AJAX-Aufruf für eine absichtlich langsame Seite verwenden, um einen Ruhezustand zu emulieren, aber Sie erhalten nicht die gewünschten Ergebnisse. Warum stellen Sie nicht einfach sicher, dass Ihr IFrame geladen wird, bevor die unveränderbare Funktion aufgerufen wird?

    
Zeki 02.01.2011 00:21
quelle
2

Was Sie wirklich brauchen, ist ein Ereignis, das ausgelöst wird, wenn der iFrame-Inhalt geladen wurde. Dies ist wirklich sehr einfach, da die Seite im iFrame über eigene Ereignisse verfügt und auf Skripts auf der übergeordneten Seite zugreifen kann. Sie müssen den Inhalt des iFrames jedoch ändern können.

In Ihrem iFrame benötigen Sie diesen Code.

%Vor%

Dann erstellen Sie auf Ihrer Parent-Seite eine Funktion mit dem Namen "myFunction" und legen Sie alle Skripte, die Sie dort einsetzen müssen. Dies sollte jedes Mal funktionieren.

Bearbeiten: Damit das funktioniert, brauchen Sie zwei Funktionen. Ich gehe davon aus, dass das wirklich keine Option ist, also hacken wir die eine Funktion, um zwei Funktionen zu enthalten, und rufen den richtigen Teil auf, wenn wir es brauchen.

%Vor%

Das Skript im iFrame sollte nun wie folgt geändert werden:

%Vor%

Ich habe es nicht getestet, aber theoretisch sollte es das tun

    
James Long 02.01.2011 00:15
quelle
1

Eine verblüffend einfache; -} Antwort mit XPCOM:

%Vor%

Funktioniert in der letzten Version von Firefox. Entschuldige keine Hoffnung für den Explorer!

    
Charles Bradshaw 27.09.2011 22:23
quelle
1

Eine rekursive Funktion könnte in diesem Fall helfen. Rufen Sie die Funktion einfach auf, bis eine globale Variable anzeigt, dass der Frame geladen ist

%Vor%     
robert 01.07.2012 08:03
quelle
0

Warum können Sie den Basiscode nicht ändern? Zum Beispiel könnte es ziemlich einfach sein, die Kernfunktion von

zu ändern %Vor%

Zu etwas wie diesem:

%Vor%

Wenn das für Sie nicht funktioniert, wie wäre es mit einer transparenten Änderung des ursprünglichen Codes? Kompilieren Sie es mit Javascript-Stränge und verwenden Sie die integrierte Futures-Unterstützung, um dies zu handhaben. Beachten Sie, dass Javascript 1.7 auch Fortsetzungen unterstützt, aber den Code manuell ändern müsste, um sie zu verwenden.

    
Dark Falcon 02.01.2011 00:16
quelle
0

Eine andere Lösung, die möglicherweise nicht anwendbar ist, je nachdem, wie sehr Sie den ursprünglichen Code vereinfacht haben. Sie könnten einen Onload-Handler setzen, dann einen Fehler auslösen und dann in Ihrem Onload-Handler unChangeableFunction aufrufen:

%Vor%

Diese Funktion (wie unChangeableFunction ) wird zweimal aufgerufen: einmal in der ersten Instanz, dann erneut, wenn der onload -Handler ausgelöst wird. Die zwei verschiedenen Wege spiegeln dies wider.

Auch dies ist Hacky und ein definitiver Missbrauch der Fehlerfunktion von JS.

    
lonesomeday 02.01.2011 00:39
quelle
0

Sie können Cookie und setTimeout so verwenden:

in blank_frame.html ein Skript hinzufügen:

%Vor%

Grundsätzlich fügen Sie einen Cookie iframe_loaded mit dem Wert yes hinzu. IMO ist es besser, den Cookie zu entfernen, da Sie das gleiche tun müssen, wenn Sie die Seite neu laden. Sie können die Domäne auch im setCookie Funktionsaufruf einstellen.

Nun werden wir in der Hauptdatei setTimeout mit der Funktion verwenden, die prüft, ob der Cookie existiert. Wenn dies der Fall ist, gibt die Funktion iframe wie in Ihrem Code zurück:

%Vor%

Da in dieser Datei auch ein fehlersicherer Cookie gelöscht wird. Hoffentlich gibt dir das etwas, mit dem du arbeiten kannst:)

Prost

G.

    
Gregory Machon 02.01.2011 00:40
quelle

Tags und Links