AJAX und .length funktioniert nicht.

Jan-Frederik Stieler

Monsterator
Moderator
Hallo,
ich habe folgende die Ausgangssituation.
Eine Webseite mit einem Feld von Anchors, einem Inhaltsbereich und ein Navigationsbereich.
Wird einer der Anchors gedrückt wird per Ajax ein Inhalt in den Inhaltsbereich geladen und aus diesem per Ajax geladenen Inhalt wird eine Navigation in den Navigationsbereich geladen.
Drückt man einen anderen Link wird das Div geleert und der neue Inhalt dort wieder per ajax reingeladen.
Nun habe ich aber das Problem, dass ich nun zwei Inhalte im Navigationsbereich liegen habe. Einmal vom ersten geladen Inhalt und einmal vom zweiten.

Wenn ich nun versuche zu überprüfen ob sich in dem Navigationbereich den schon was befindet, aus dem Ajaxinhalt herraus, bekomme ich immer null. Ich kann also nicht per .length überprüfen ob ich schon eine Navigation auf der Seite habe.
Was mach ich den nun um nicht mehrere Navigationen reingeladen zu bekommen?

Javascript:
	var ajaxContent 		=	$('.ajaxContent'),
		ajaxContentControl	=	$('li.ajaxcontentcontrol');

	$('.ajaxcontentcontrol').remove('.ajaxcontentcontrol');
	
	if ( $('.contentcontrol .ajaxcontentcontrol').length === 0  ) {
		$('.contentcontrol>ul li:first-child').before(ajaxContentControl);
		ajaxContentControl.hide().fadeIn('slow');
	}
	else {	
		$('.contentcontrol>ul li.ajaxcontentcontrol').remove();
		$('.contentcontrol>ul li:first-child').before(ajaxContentControl);
		ajaxContentControl.hide().fadeIn('slow');
	}


Grüße
 
Hi,

du hast mit
Code:
$('.ajaxcontentcontrol').remove('.ajaxcontentcontrol');
alle Element mit der Klasse .ajaxcontentcontrol aus dem DOM entfernt. Du hast nur noch Referenzen hierfür in der Variable ajaxContentControl. Vielleicht solltest du diese prüfen.
Code:
if ( ajaxContentControl.length === 0  ) {
Ciao
Quaese
 
Dieser Aufruf:
$('.ajaxcontentcontrol').remove('.ajaxcontentcontrol');
löscht ALLE Elemente mit der Klasse ajaxcontentcontrol
http://jsfiddle.net/K3Gec/

Diese nachträgliche Afrage:
$('.contentcontrol .ajaxcontentcontrol').length === 0
macht also gar kein Sinn mehr, es gibt keine Elemente mit class="ajaxcontentcontrol".

Eventuell mehr code posten oder das ganze selbst nochmals durchdenken :)

Grüsse
 
Hi jeipack,
doch es gibt noch die Klasse .ajaxcontentcontrol. Nämlich dadurch das die if-Abfrage immer 0 ausgibt wird ja die Referenz in contentcontrol eingefügt.
Und falls diese eben nicht vorhanden ist soll das else ausgeführt werden. Da ich aber immer 0 ausgegeben bekomme unabhängig ob .ajaxcontentcontrol in .contentcontrol vorhanden ist.
Ich denke das Script in dem Ajaxaufruf kann irgendwie das Dom vom Rest nicht überprüfen.

Ihr könnt euch das Konstrukt auf:
(Inhalt der per Ajax aufgerufen wird) http://jsbin.com/AvuKoLE/14/edit
und
(Seite in die der Ajaxinhalt geladen wird) http://jsbin.com/UGuvAqi/4/edit
anschauen

Grüße
 
@jeipack

Die Methode remove entfernt zwar die Elemente aus dem DOM, die zugehörigen Objekte existieren allerdings weiter (deshalb sicherlich auch remove und nicht delete). In der Variablen aus dem Ausgangscode sind deshalb noch immer die Referenzen auf die Objekte enthalten und es gibt eine Länge.

Beispiel:
Code:
<html>
<head>
<title>www.tutorials.de</title>
<meta name="author" content="Quaese" />
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
$(function(){
    weg = $('.weg');
    weg.remove('.weg');
    console.log(weg.length);
})
</script>
</head>
<body>
<ul>
  <li class="weg">eins</li>
  <li><span class="weg">zwei</span></li>
</ul>
</body>
</html>
In der Console sollte weiterhin 2 ausgegeben werden.

Ciao
Quaese
 
@Jan-Frederik

Du erwartest offensichtlich, dass das Script aus dem mittels Ajax nachgeladenen ausgeführt wird - das ist jedoch nicht der Fall. Vielmehr müsstest du die gewünschten Effekte vom auslösenden Dokument aus steuern (per live-Event und callback-Funktionen).

Hier ein Lösungsansatz, der aber sicherlich nur bedingt funktioniert, aber die Vorgehensweise demonstriert.
Code:
<!DOCTYPE html>
<html lang="de">
  <head>
    <meta name="description" content="ajaxtest" />
    <!-- CSS -->
    <link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css" rel="stylesheet">
    <link href="http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet" />
	<link href="http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome-ie7.min.css" rel="stylesheet">
    <link href="http://fonts.googleapis.com/css?family=Titillium+Web:400,300,600,700" rel="stylesheet" type="text/css">
    <!-- Javascript -->
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
	<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
    <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
    <script type="text/javascript">
	$(function(){
	  	var ajaxContent = $('.ajaxContent');

	  	$('.filter-table a').click(function(ajaxClick){
			ajaxClick.preventDefault();

			var contentToLoad = $(this).attr('href');

	        console.log(contentToLoad);

			if (ajaxContent.is(':empty')){
				ajaxContent.html('<span class="icon-refresh icon-spin icon-large ajaxLoader" aria-hidden="true"></span><span class="hide">Inhalt wird geladen.</span>');
				ajaxContent.load(contentToLoad).fadeIn('slow', function() {
					handleAjaxContent();
				});
			}
			else {
				ajaxContent.html('<span class="icon-refresh icon-spin icon-large ajaxLoader" aria-hidden="true"></span><span class="hide">Inhalt wird geladen.</span>');
				ajaxContent.load(contentToLoad, function() {
					ajaxContent.hide().fadeIn('slow');
					handleAjaxContent();
				});
			}
			history.pushState({}, '', contentToLoad);
			$(this).addClass('active');
		});

		// AJAX content remove (live event)
	    $('.contentcontrol').on('click', '.unload', function(){
	        ajaxContent.children().fadeOut('slow', function(){
	            $(this).remove();
	            $('.ajaxcontentcontrol').fadeOut('slow', function(){
	                $(this).remove();
	            });
	        });
	    });

	    // prev/next Handling (live event)
	    $('.contentcontrol').on('click', '.next a, .prev a', function(ajaxClick){
	        ajaxClick.preventDefault();

	        var contentToLoad = $(this).attr('href');

	        if (ajaxContent.is(':empty')){
	            ajaxContent.html('<span class="icon-refresh icon-spin icon-large ajaxLoader" aria-hidden="true"></span><span class="hide">Inhalt wird geladen.</span>');
	            ajaxContent.load(contentToLoad).fadeIn('slow');
	        }
	        else {
	            ajaxContent.html('<span class="icon-refresh icon-spin icon-large ajaxLoader" aria-hidden="true"></span><span class="hide">Inhalt wird geladen.</span>');
	            $('.ajaxcontentcontrol').css('display', 'block');
	            ajaxContent.load(contentToLoad, function() {
	                ajaxContent.hide().fadeIn('slow');
	            });
	        }
	        history.pushState({}, '', contentToLoad);
	        $(this).addClass('active');
	    });
	});

	// callback-Funktion
	function handleAjaxContent(){
	    var ajaxContent         =   $('.ajaxContent'),
	        ajaxContentControl  =   $('li.ajaxcontentcontrol');

	    $('.ajaxcontentcontrol').remove('.ajaxcontentcontrol');

	    if ( ajaxContentControl.length === 0  ) {
	        $('.contentcontrol>ul li:first-child').before(ajaxContentControl);
	        ajaxContentControl.hide().fadeIn('slow');
	    }
	    else {
	        $('.contentcontrol>ul li.ajaxcontentcontrol').remove();
	        $('.contentcontrol>ul li:first-child').before(ajaxContentControl);
	        ajaxContentControl.hide().fadeIn('slow');
	    }
	}
    </script>
    <title>Bootstrap Template</title>
  </head>

  <body class="container">
    <!-- Help Area-->
    <nav class="navbar navbar-default navbar-top" role="navigation">
      <div class="navbar-header">
        <a class="navbar-brand" href="#">Help:</a>
      </div>
      <ul class="nav navbar-nav">
        <li><a href="http://www.getbootstrap.com" target="_blank">Bootstrap</a></li>
        <li><a href="http://fontawesome.io/icons/" target="_blank">Font Awesome</a></li>
      </ul>
    </nav>

    <div class="row">
      <ul class="nav nav-pills filter-table">
        <li><a href="ajax_inhalt_der_nachgeladen_werden_soll.html">test01</a></li>
        <li><a href="ajax_inhalt_der_nachgeladen_werden_soll.html">test02</a></li>
      </ul>
    </div>
    <div class="row">
      <div class=" col-md-6 ajaxContent">
      </div>
      <div class="col-md-4 pull-right contentcontrol">
        <ul>
          <li><button class="btn btn-default">suche</button></li>
        </ul>
      </div>
    </div>
  </body>
</html>
Vielleicht kannst du damit etwas anfangen.

Ciao
Quaese
 
Hi,
Du erwartest offensichtlich, dass das Script aus dem mittels Ajax nachgeladenen ausgeführt wird - das ist jedoch nicht der Fall.
Ja das tue ich :). Also das Script wird ja auch per click auf den Schlißen-Button ausgelöst warum nicht auch mittels $(function(){}); wenn der Inhalt per Ajax geladen wurde ?
Wäre super nett, wenn du mir das vielleicht erklären könntest, ich habe hier eine Wissenslücke :).

Ich probiere dein Script morgen mal aus.

Viele Grüße und vielen Dank!
 
Hi,

sieht doch so aus, als würde der Inhalt des Scripts ausgeführt werden (jQuery) - da habe ich mich wohl geirrt.

Allerdings scheint es nicht an der Position zu funktionieren. Schiebe ich es an den Anfang des Ajax-Inhalts und lasse einfach zu Testzwecken einen Alert ausgeben, funktioniert es.

Du solltest auch ausprobieren, ob der ready-Event feuert, wenn du das Fragment einbindest. Eventuell musst du das Ausführen des gewünschten Codes selbst anstossen.

Ciao
Quaese
 
@Quaese:
Ja so stimmts natürlich. Aber dein Beispiel entspricht nicht dem ersten Post, weil dann würde es eher so aussehen:
Javascript:
$(function(){
    weg = $('.weg');
    weg.remove('.weg');
    console.log($('.weg').length);
})
Und das wird immer 0 geben. (Dies prüft nämlich nicht die Variable, sondern will mit einem Selektor nochmals alle Elemente mit der Klasse weg selektieren, was natürlich nicht mehr geht.
Aber soviel nur dazu, das ist ja inzwischen eh korrigiert :)

Was mir bei den JS Bins auf den ersten Blick gerade auffällt:
Javascript:
ajaxContentControl	=	$('li.ajaxcontentcontrol');

	$('.ajaxcontentcontrol').remove('.ajaxcontentcontrol');
	
	if ( $(ajaxContentControl).length === 0  ) {

Die Variable ajaxContentControl ist schon ein jQuery Objekt, du musst es nicht nochmals in ein jQuery Objekt wrappen. Allerdings hat das überhaupt nichts mit deiner eigenen Fragestellung zu tun.

Also, damit ich es richtig verstehe, dich stört, dass das Script das nachgeladen wird, nicht auf den DOM zugreifen kann? Also dass:
Javascript:
$('.ajaxcontentcontrol').remove('.ajaxcontentcontrol');
nicht alle '.ajaxcontentcontrol' removed, obwohl es solche auf der Seite hat?
Würde man dies im Hauptdokument aufrufen, würde es jedoch klappen?

Versteh ich das jetzt so richtig? :)
 
Hi,
Die Variable ajaxContentControl ist schon ein jQuery Objekt, du musst es nicht nochmals in ein jQuery Objekt wrappen.
Oh stimmt. Hab ich ganz übersehen. Danke.

Also das mit der Klasse ajaxcontentcontrol ist etwas verwirrend da ich diese zwei mal verwende.
Einmal für ein ul und für ein li und dann wird nur das li.ajaxcontrol neu eingefügt und ul.ajaxcontrol wird removed.

Also mein Problem ist das die if-Abfrage nicht funktioniert. Die Steuerung wird ja mehrmals reinkopiert wenn ich einen anderen Ajaxlink drücke.

Das
$('.ajaxcontentcontrol').remove('.ajaxcontentcontrol');
wird ausgeführt.

Also nächste Testphase :).

Grüße
 
Zurück