jQuery $ (document) .ready () wird zweimal ausgelöst


73

Ich habe im Internet herumgesucht, um herauszufinden, was hier vor sich geht, und konnte keine konkrete Antwort erhalten.

Ich habe eine $(document).readyauf meiner Site, die unabhängig vom darin enthaltenen Code mehrere Male ausgeführt werden kann.

Ich habe in den Fehlerberichten für jQuery nachgelesen, wie das .readyEreignis zweimal ausgelöst wird, wenn in Ihrer Anweisung eine Ausnahme auftritt. Aber selbst wenn ich den folgenden Code habe, läuft er immer noch zweimal:

$(document).ready(function() {
    try{    
        console.log('ready');
        }
    catch(e){
        console.log(e);
    }
});

In der Konsole wird nur zweimal "fertig" protokolliert. Ist es möglich, dass ein anderer. Bereits mit einer Ausnahme ein Problem verursacht? Mein Verständnis war, dass alle .ready-Tags unabhängig voneinander waren, aber ich kann anscheinend nicht herausfinden, wo dies ins Spiel kommt?

Hier ist der Kopfblock für die Site:

<head>
<title>${path.title}</title>
<meta name="Description" content="${path.description}" />
<link href="${cssHost}${path.pathCss}" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="media/js/fancybox/jquery.fancybox.pack.js" type="text/javascript" ><!-- --></script>
<script src="/media/es/jobsite/js/landing.js" type="text/javascript" ><!-- --></script>
<script src="/media/es/jobsite/js/functions.js" type="text/javascript"><!-- -->    </script>
<script src="/media/es/jobsite/js/jobParsing.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="/media/es/jobsite/js/queryNormilization.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="${jsHost}/js/jquery/jquery.metadata.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="${jsHost}/js/jquery/jquery.form.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js" type="text/javascript" charset="utf-8"><!----></script>
<script src="${jsHost}/js/jquery.i18n.properties-min.js" type="text/javascript" charset="utf-8"><!----></script>

<script type="text/javascript" charset="utf-8">

function updateBannerLink() {
    var s4 = location.hash.substring(1);
    $("#banner").attr('href','http://INTELATRACKING.ORG/?a=12240&amp;c=29258&amp;s4='+s4+'&amp;s5=^');
}

</script>
</head>

Achten Sie nicht auf die JSP-Variablen, aber wie Sie sehen, rufe ich die Datei functions.js nur einmal auf (dort ist die Funktion .ready vorhanden).


2
Verursacht etwas eine Seitenaktualisierung oder ein Laden einer zweiten Seite - eine Art Debugging-Tool wie Firebug oder so?
Dylan Beattie

1
Es wird nur einmal für mich protokolliert .
Elliot Bonneville

Können Sie Informationen zur verwendeten Version von jQuery und zu den Browsern geben, in denen dies geschieht?
Victor

1
Ich würde vermuten, dass der gleiche Code zweimal eingebettet ist. Das DOM-Ready-Ereignis wird einmal ausgelöst, wenn das DOM bereit ist. Der Ready-Handler bindet einfach an dieses Ereignis. Wenn es zweimal gebunden wird, wird es zweimal ausgeführt. Möglicherweise sollten Sie nach Javascript suchen, um festzustellen, ob dieser Code an einer anderen Stelle wiederholt wird, oder Sie haben gerade ein Konsolenprotokoll in einem anderen Handler hinterlassen, in dem ein anderer Code ausgeführt wird, aber Sie haben gerade ein Konsolenprotokoll hinterlassen.
Alok Swain

@ngen - Sicher ist es hier, jsfiddle.net/alokswain/xNEtg .. der Grund dafür ist, dass wir nur das Ereignis anhören und es mehrmals anhören können, nur ein einfacher Fall von mehreren Bindungen an ein einzelnes Ereignis: das Dokument bereit, das einmal ausgelöst wird.
Alok Swain

Antworten:


66

Das Ready-Ereignis kann nicht zweimal ausgelöst werden. Es ist mehr als wahrscheinlich, dass Sie Code haben, der das Element, in dem der Code enthalten ist, verschiebt oder manipuliert, wodurch der Browser den Skriptblock erneut ausführt.

Dies kann vermieden werden, indem Skript-Tags in das <head>oder vor dem schließenden </body>Tag eingefügt und nicht verwendet werden $('body').wrapInner();. Verwenden $('body').html($('body').html().replace(...));hat den gleichen Effekt.


Ich verwende das .wrapInner () -Tag überhaupt nicht auf meiner Site, und soweit ich das beurteilen kann, sind alle Skript-Tags in den <head> </ head> -Tags meiner Site enthalten, also nicht sehen, wie der Code "erneut ausgeführt" werden könnte?
Xenology

Wo wird updateBannerLink aufgerufen? Wenn es sich in einem Ankertag befindet, verhindern Sie dann, dass das Ankertag die Seite neu lädt?
Kevin B

Eigentlich ist das eine blöde Frage. Keine Ursache. Wenn es zweimal ohne Interaktion von Ihnen passiert, muss der Code zweimal irgendwo enthalten sein, wenn der Code in der<head>
Kevin B

10
Das Problem hier war schließlich ein IFRAME-Tag, das auf der Seite enthalten war. Beim Entfernen des Dokuments. Bereits nur einmal ausgelöst. Wie Sie sehen, gibt es einen offensichtlichen Grund, warum das Tag ein erneutes Laden der Seite verursacht. <Iframe id = "pathIframe" frameborder = "0" height = "600" width = "100%" name = "path" scrollt = "auto" src = "#"> </ iframe>
Xenology

8
Vermeiden Sie die Verwendung von src="#"Attributen, da dieselbe Seite im übergeordneten Fenster und im Iframe geladen wird. Daher sieht es so aus, als würde Code zweimal aufgerufen. Entfernen Sie das srcAttribut oder setzen Sie es auf "about:blank", um ein solches Verhalten zu vermeiden.
Inferpse

41

Es ist mir auch passiert, aber ich habe festgestellt, dass das Skript aufgrund einer schlechten Zusammenführung zweimal enthalten war.


In asp.net mvc habe ich vermisst, dass ich ein Bundle hatte, das alle js eines Ordners enthielt, und ich habe ein weiteres für die einzelne Datei erstellt, was 2 Einschlüsse derselben Datei
ergab

Ich habe das gleiche Skript sowohl in das Laravel-Layout als auch in die dynamische Seite aufgenommen. Das Entfernen der Aufnahme in die dynamische PHP-Datei löste das Problem für mich.
Prasanna Kumar

Vielen Dank, dass Sie dies erwähnt haben. Es ist ziemlich offensichtlich, aber Ihre Antwort hat mich dazu gebracht, meine Includes zu überprüfen, was das Problem gelöst hat;)
Florieger

Ja, mir ist das gleiche Problem passiert, das versehentlich zweimal dasselbe Skript enthielt.
RKM

34

Dies ist mir bei der Verwendung von KendoUI passiert. Wenn Sie ein Popup-Fenster aufrufen, wird das document.readyEreignis mehrmals ausgelöst . Die einfache Lösung besteht darin, ein globales Flag so zu setzen, dass es nur einmal ausgeführt wird:

var pageInitialized = false;
$(function()
{
    if(pageInitialized) return;
    pageInitialized = true;
    // Put your init logic here.
});

Es ist eine Art Hack-ish, aber es funktioniert.


14

Stellen Sie sicher, dass Sie die JS-Datei nicht zweimal einschließen. Das war mein Fall


Guter Anruf! Ich habe mein Skript von einem $ .getScript aus einem anderen Hauptskript aufgerufen. Aber ich habe vergessen, dass ich zum Debuggen ein <script> -Tag hinzugefügt habe!
Jeff

3

Sie könnten in Betracht ziehen, zu verwenden

window.onload

anstatt

$(document).ready

1
Ich möchte nur sagen, dass das bei mir funktioniert hat. Bei der Arbeit mit Google Maps wurden meine Inhalte irgendwie zweimal ausgelöst, aber window.onload anstelle von document.ready hat bereits für mich funktioniert, also danke.
Balslev

2

Versuchen Sie, dies in Ihre functions.js einzufügen, um zu verhindern, dass es zweimal ausgeführt wird:

var checkit = window.check_var;
if(checkit === undefined){ //file never entered. the global var was not set.
    window.check_var = 1;
}
else {
    //your functions.js content 
}

Ich schlage jedoch vor, dass Sie mehr darüber nachdenken, um zu sehen, wo Sie das zweite Mal anrufen.


Ich wollte so etwas als chaotisch vermeiden, und ich mag die Idee nicht, diese Funktionalität zusammen hacken zu müssen. Obwohl dies möglicherweise die einzige Lösung ist, die ich habe, wenn ich das nicht herausfinden kann
Xenology

Ich wollte hier nur hinzufügen, obwohl dies sehr hackig ist, ist es auch falsch. Die Syntax sollte in "if (typeof checkit === 'undefined')" geändert werden. Typeof gibt immer eine Zeichenfolge zurück.
Zach Pedigo

1

Ich hatte ein ähnliches Problem, als ich versuchte, einen Teil zu aktualisieren. Ich habe ein return ActionResult anstelle eines return PartialViewResult aufgerufen. Das ActionResult hat dazu geführt, dass mein ready () zweimal ausgeführt wurde.


1

Es besteht die Möglichkeit, dass dieses Problem auftritt, wenn Sie denselben Controller zweimal im HTML-Code hinzufügen.
Zum Beispiel:
[js]

app.controller('AppCtrl', function ($scope) {
 $(document).ready(function () {
        alert("Hello");
        //this will call twice 
    });
});

[html]

//controller mentioned for the first time
<md-content ng-controller="AppCtrl">
    //some thing
</md-content>

//same controller mentioned again 
<md-content ng-controller="AppCtrl">
    //some thing
</md-content>


0

In meinem Fall wurde $ (document) .ready wegen schlechten CSS zweimal ausgelöst. Überprüfen Sie, ob ein Teil Ihres CSS vorhanden ist background-image: url('');


CSS kann keine Ereignisse beeinflussen.
Hexodus

0

Wenn der Iframe nichts anzeigt und aus anderen Gründen verwendet wird (z. B. zum Hochladen einer Datei ohne erneutes Laden), können Sie Folgendes tun:

<iframe id="upload_target" name="upload_target" style="width:0;height:0;border:0px solid #fff;"></iframe>

Beachten Sie, dass src nicht enthalten ist, wodurch verhindert wird, dass der zweite Bereitschaftsauslöser im Dokument ausgelöst wird.


0

Ich hatte dieses Problem mit der window.load-Funktion wurde zweimal ausgeführt: Der Grund war, dass ich auf der Hauptseite auf dieselbe Javascript-Datei sowie auf eine .net-Benutzersteuerung verwiesen hatte. Als ich den Verweis auf der Hauptseite entfernte, wurde die Ladefunktion nur einmal ausgeführt.


0

Das ist mir heute Morgen passiert ... und was ich herausgefunden habe, nachdem ich einen HTML-Code in einer kürzlich manipulierten jquery-modalen Form genau untersucht hatte, dass ich versehentlich ein schließendes Tabellen-Tag entfernt hatte. Ich habe mir noch nicht die Zeit genommen, um vollständig zu verstehen, warum die Funktion document.ready dadurch zweimal aufgerufen wurde , aber es tat es. Durch Hinzufügen des Closing Table-Tags wurde dieses Problem behoben.

jQuery JavaScript Library v1.8.3 (ja, es ist eine Legacy-App)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.