# JQuery - document(ready) wird zwei mal geworfen



## Trash (8. Juli 2012)

Hallo,
ich habe ein seltsames Phänomen mit JQuery. Bei mir wird 


```
$(document).ready(function(){	
console.log('init');
```

zwei mal aufgerufen. Dies passiert nur, wenn ich die Seite initial betrete. Wenn ich die Seite betreten habe und einen einfachen reload mache, wird $(document).ready nur einmal aufgerufen. 

Weiß jemand warum das so ist und wie ich es verhindern kann, dass das Event zwei Mal geworfen wird?


----------



## erik s. (8. Juli 2012)

Kannst du etwas mehr Quelltext preisgeben?


----------



## CPoly (8. Juli 2012)

Ich kann es mir zwar nicht vorstellen, aber verwendest du eine völlig veraltete jQuery Version 1.4.3?

Falls nein, dann



erik s. hat gesagt.:


> Kannst du etwas mehr Quelltext preisgeben?


----------



## Trash (9. Juli 2012)

Hallo,
ich nutze JQuery 1.7 und das ganze taucht folgendermaßen auf:

Ich habe eine index.php, die ein Menü besitzt. Klickt man auf einen Menüpunkt wird die entsprechende HTML/PHP-Seite per $.ajax in ein bestimmtes Div geladen. 

Die per Ajax geladene Datei ist eine "normale" HTML-Datei, die PHP-Elemente besitzt und eben auch über das normale Grundgerüst verfügt <html><body><head>. Im <head> der zu inkludierenden Datei wird dann die jeweilig für den Menüpunkt wichtige JS-Datei inkludiert - sie wird in der index.php nicht inkludiert. 

Dieser .js-Datei habe ich das obige Beispiel entnommen. Wenn ich nun die Seite initial aufrufe und das erste Mal auf den Menüpunkt klicke, wird die Seite in das Div geladen und "init" wird zwei mal geworfen. Mache ich z.B. einen reload der gesamten Page oder klicke auf einen anderen Menüpunkt und wieder zurück, wird es nur einmal geworfen.

Das ganze macht bei mir Probleme, da ich eine Funktion (siehe unten) habe bei der ich einen Suchbegriff eingeben kann und nach Klick auf das Suchergebnis (li.search_list_item) soll der geklickte Inhalt in ein anderes Div übertragen werden (#searchresult). Das Problem ist nun, dass bei dem ersten Aufruf des Menüpunkt und der Nutzung der Suche, das geklickte Element zwei Mal hinzugefügt wird! Komischerweise taucht dieses Phänomen im Firefox auf, im Safari aber nicht - obwohl das 'init' auch im Safari zwei Mal ausgegeben wird.


```
$(document).ready(function(){
    $('#searchresult').on('click', 'li.search_list_item', function(){

    $('#msg_receiver').append('<li class="single_receiver" id="single_receiver_'+$(this).attr('id')+'">'+$(this).find('span').html()+'</li>');

    $('#single_receiver_'+$(this).attr('id')).hide().fadeIn(500);

    });
});
```

Ich habe es auch schon mit event.stopPropagation(); versucht, was aber nichts geholfen hat - obwohl ich function() um function(event) erweitert habe.

Wäre für Ratschläge seeeeeeeeeeeehr dankbar!


----------



## CPoly (9. Juli 2012)

Wenn überhaupt, dann müsstest du stopImmediatePropagation() benutzen http://api.jquery.com/event.stopImmediatePropagation/

Aber bevor du jetzt jubelst und das als erledigt markierst, das löst ja nicht dein Problem, es versteckt nur die Auswirkungen.

Ich verstehe nicht ganz wieso du das machst. Das klingt nach einem ziemlichen durcheinander.

Wieso enthält die eingebundene Datei ebenfalls ein komplettes HTML Gerüst? Wieso wird das überhaupt dynamisch geladen? Ich sehe da diverse Problem, wenn du z.B. einen zweiten Menüpunkt auswählst, bleibt das JavaScript des vorherigen aktiv. Das ist unsauber.

Edit: Eine andere schnelle und unsaubere Lösung wäre die Verwendung von "one('ready')" http://api.jquery.com/one/


----------



## Trash (9. Juli 2012)

Moin,
meine Absicht dabei war, dass ich pro eingebundenem Menüpunkt nicht alle JS-Funktionen benötige. Bevor ich in der index.php 10 verschiedene JS-Dateien habe, die ich alle inkludiere, wollte ich der Übersicht halber pro inkludierter Datei eine eigene js-Datei haben.

Meinst Du, das zweifache ausführen von $.document(ready) liegt daran und verschwindet, wenn ich die inkludierende Datei ohne vollständiges HTML-Gerüst einbinde und das .JS vorher in der index.php inkludiere? Ich dachte, dass das .js der index.php evtl. nicht aktiv wird, da die andere Datei später dynamisch dazugeladen wird...warum ich das mache hat den einfachen Grund, da ich es "schön" finde, wenn sich lediglich ein Div mit dem Content ändert, als das die ganze Seite neugeladen wird.

Zusammengefasst ist es besser alle .js Dateien in der index.php zu inkludieren und das JS in den per Ajax nachgeladenen HTML/PHP-Dateien funktioniert dann trotzdem?


----------



## CPoly (9. Juli 2012)

Trash hat gesagt.:


> meine Absicht dabei war, dass ich pro eingebundenem Menüpunkt nicht alle JS-Funktionen benötige. Bevor ich in der index.php 10 verschiedene JS-Dateien habe, die ich alle inkludiere, wollte ich der Übersicht halber pro inkludierter Datei eine eigene js-Datei haben.



Wie groß sind die denn? Du kannst auch alle Dateien in eine Stecken.



Trash hat gesagt.:


> Zusammengefasst ist es besser alle .js Dateien in der index.php zu inkludieren und das JS in den per Ajax nachgeladenen HTML/PHP-Dateien funktioniert dann trotzdem?



Ich wüsste nicht, wieso das andere JS dann nicht funktionieren sollte. Das solltest du doch schnell ausprobieren können.


Vielleicht kommst du auch damit weiter http://requirejs.org/


----------



## Trash (9. Juli 2012)

Also, wenn ich es so verändere, dass die zu inkludierende JS-Datei in der index.php aufgerufen wird, greifen die Event-Handler nicht mehr. Selbst mit on('click','.klasse'... geht es nicht. Das ist doch sehr seltsam. Ich denke hier ist das Problem, dass das JS geladen wird, die angesprochenen Klassen aber noch gar nicht existieren - aber dafür gibt es ja eigentlich on()...

RequireJS gucke ich mir mal an.


----------



## CPoly (9. Juli 2012)

Kannst du das nicht mal irgendwo hochladen? Wäre ganz hilfreich.


----------



## Trash (9. Juli 2012)

Die Seite ist mittlerweile ziemlich komplex. Ich versuche mal später/morgen ein ähnliches Beispiel bereitzustellen. (event.stopImmediatePropagation funktioniert übrigens!).


----------



## Trash (9. Juli 2012)

Hm, ich habe versucht ein ähnliches Beispiel zu programmieren.

index.php

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       "http://www.w3.org/TR/html4/loose.dtd">
<html lang="de">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>Testscript</title>
		<meta name="description" content="Testscript.">
		<script src="js/jquery.js"></script>
		<script src="js/index.js"></script>
	</head>
	<body>
		<div class="menu">
		<span>Testmenu</span>
		</div>	
		<div class="content">
		</div>
	</body>
</html>
```

index.js

```
$(document).ready(function(){

	$('.menu span').click(function() {
		//laden des contents
		$.ajax({
			type: "GET",
			url: "content.php",
		       					
		    success: function(data){
				$('.content').html(data);
		    }
		});//ajax
	});
});
```

content.php

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       "http://www.w3.org/TR/html4/loose.dtd">
<html lang="de">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>Testscript</title>
		<meta name="description" content="Testscript.">
		<script src="js/content.js"></script>
	</head>
	<body>
		Dies ist der Inhalt! <span class="link">click</span>
	</body>
</html>
```

content.js

```
$(document).ready(function(){

	console.log('init');	

	$('.link').click(function() {
		alert("ja");		
	});
	
});
```

Wenn Du jetzt den JS-Code aus der content.js in die index.js schiebst, ****t es natürlich nicht mehr wenn Du auf "click" drückst, da zum Zeitpunkt des JS-Ladens die Klasse .link noch nicht kennst - da diese ja erst durch den $.ajax-Befehl kommt. Deswegen muss man in der index.js nun "on" benutzen:


```
$('.content').on('click','.link', function() {
		alert("ja");		
	});
```

Dann geht es. Das ist das was ich vorhin erklären wollte. Man nimmt den JS-Code in die index.php und arbeitet mit .on(). Warum dies nun bei meinem Projekt nicht geht - weiß ich noch nicht. Evtl. ist es mittlerweile so komplex geworden, dass irgendetwas diesen Befehl blockiert...ich werde es wohl mit stopImmediate... erstmal belassen und mir evtl. später, wenn ich mehr Zeit habe nochmal in Ruhe im Detail auseinandernehmen....

Danke für deine Hilfe - falls Du noch Idee hast, immer her damit


----------



## CPoly (9. Juli 2012)

Ich bekomme nur einmal "init" ausgegeben. Das Problem muss woanders liegen.


----------

