# jQuery - index eines dynamisch geladenen Elements auslesen



## BoR (24. Oktober 2013)

Hallo,
ich sitze gerade an einer Projektgalerie. Heisst, ich habe einen Container in dem sich mehrere Bilder befinden.


```
<div id="projektContainer">
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
</div
```

Bei einem Klick auf ein jeweiliges Bild wird an einer bestimmten Stelle zwischen den Bildern dynamisch ein neuer Container mittels .after() und dessen darin enthaltene Informationen mittels .load() eingefügt.
Danach sieht das ganze z.B. so aus:


```
<div id="projektContainer">
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
    <div id="projektDetails">
        <h1>...</h1>
        <p>...</p>
        <img ... />
    </div>
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
</div
```

Wenn ich nun die Breite des Browserfensters ändere, soll "projektDetails" im Index z.B. eine Position nach oben oder unten rutschen. Somit wäre es dann nicht mehr Nr. 4 im "projektContainer", sondern Nr. 3. Wenn ich allerdings einfach den Index von "projektDetails" auslesen möchte, bekomme ich -1 zurückgegeben, da das Element im DOM-Baum nicht gefunden wird, weil es dynamisch erzeugt wurde.


```
$("img:eq(2)").index(this)
```
 -> ergibt Bild Nr. 3

```
$("img:eq(3)").index(this)
```
 -> ergibt Bild Nr. 4

*Gibt es hierbei eine Möglichkeit den Index von "projektDetails" "sichtbar zu machen" und das DOM zu manipulieren?*


Gruß Lars


----------



## Quaese (24. Oktober 2013)

Hi,

mit deiner Methode ermittelst du alle Bilder, die sich "unterhalb" des Knotens mit der ID *projektContainer* befinden. Du willst jedoch bestimmt nur die Bilder, die direkte Kinder sind:

```
$('#projektContainer').children('img').eq(2).index()
```

Wenn du die Bilder nur um eine Position nach oben bzw. nach unten verschieben möchtest, könntest du auch die Methoden *next* und *prev* verwenden, z.B.

HTML:

```
<div id="projektContainer">
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
    <img class="..." src="..." alt="..." />
</div
<button id="insert">insert</button>
<div id="moreButtons" style="display: none;">
    <button id="up">up</button>
    <button id="down">down</button>
</div>
```

JavaScript:

```
$(function(){
    $('#insert').on('click', function(evt){
        var neu = $('<div id="projektDetails"><h1>...</h1><p>...</p><img ... /></div>');

        $('#projektContainer img').eq(2).after(neu);
        $('#moreButtons').show();
    });
    
    $('#up').on('click', function(evt){
        var neu = $('#projektDetails');
        neu.prev().before(neu);
    });
    
    $('#down').on('click', function(evt){
        var neu = $('#projektDetails');
        neu.next().after(neu);
    });
});
```
Ciao
Quaese


----------



## jeipack (24. Oktober 2013)

Hi



> da das Element im DOM-Baum nicht gefunden wird, weil es dynamisch erzeugt wurde.


Das ist falsch. Wenn du Elemente einfügst, z.B. mit after(), dann sind sie danach auch im DOM vorhanden.

Du könntest das Image Selectieren und dannach das nächste Element nehmen. Aber es wäre viel schöner, wenn du das Image selbst in einen Container packst.


```
<div id="projektContainer">
	<div class="projectImage">
		<img class="..." src="http://www.tutorials.de/javascript-ajax/..." alt="..." />
	</div>
    <div class="projectImage">
		<img class="..." src="http://www.tutorials.de/javascript-ajax/..." alt="..." />
	</div>
	<div class="projectImage">
		<img class="..." src="http://www.tutorials.de/javascript-ajax/..." alt="..." />
	</div>
	<div class="projectImage">
		<img class="..." src="http://www.tutorials.de/javascript-ajax/..." alt="..." />
	</div>
</div
```


```
//div anfügen
$("div.projectImage:eq(2)").append("<div>Hello World</div>");

//div auswählen
$("div.projectImage:eq(2) > div").html("Hello World v2.0");
```

http://jsfiddle.net/F8kft/

greeez


----------



## BoR (24. Oktober 2013)

An .on() habe ich auch gedacht, ABER, ich muss wohl doch noch mehr erklären. 

Bild00 Bild01 Bild02 Bild03 Bild04
Bild05 Bild06 Bild07 Bild08 Bild09
Bild10 Bild11 Bild12 Bild13 Bild14

Klick auf Bild02 ->

Bild00 Bild01 Bild02 Bild03 Bild04
----------------------------------------
-----------projektDetails-------------
----------------------------------------
Bild05 Bild06 Bild07 Bild08 Bild09
Bild10 Bild11 Bild12 Bild13 Bild14

Wenn ich nun die Breite des Browser ändere, ändert sich auch die Anzahl der Bilder in einer Reihe. "projektDetails" bleibt beim Ändern natürlich offen.

Bild00 Bild01 Bild02 Bild03 
               Bild04 
-------------------------------
--------projektDetails-------
-------------------------------
Bild05 Bild06 Bild07 Bild08 
Bild09 Bild10 Bild11 Bild12 
Bild13 Bild14

Allerdings soll es bei Breitenänderung so aussehen:

Bild00 Bild01 Bild02 Bild03 
-------------------------------
--------projektDetails-------
-------------------------------
Bild04 Bild05 Bild06 Bild07 
Bild08 Bild09 Bild10 Bild11 
      Bild12 Bild13 Bild14

*Wenn das ganze auf einen Klick reagieren soll, wäre das kein Problem; allerdings soll auf ein $(window).resize() selbstständig reagiert werden und eine Anpassung stattfinden.*

Die Anzahl der Spalten auslesen und "projektDetails" an der jeweiligen Stelle einfügen kriege ich hin. Allerdings läuft die automatische Anpassung nicht wie gewünscht. Sollen Bilder z.B. über "projektDetails" wandern, tun sie dies nicht. *Und warum krieg ich bei
*

```
$("#projektDetails").index(this)
```
* ein -1 zurück; das liegt doch am dynamischen Einfügen, oder?* Würde ich den Index auslesen können, könnte ich auch die Verschiebung schreiben.


----------



## jeipack (24. Oktober 2013)

Ahh jetzt verstehe ich.

Das ist ein CSS Problem, kein Javascript. Sowas machen unsere Designer andauernd 


Ich hingegen bin nicht so ein Hirsch in CSS dass ich dir gleich auswendig sagen kann wie das gemacht wird, auf jeden Fall etwas mit floaten.

Vielleicht kann dir jemand anders helfen wie du das machen musst, ansonsten im CSS Forum wird dir sicher geholfen 

greez


----------



## BoR (24. Oktober 2013)

Ahhh, 
ich glaub, ich hab meinen Fehler gefunden. Gut, dass ich noch ein 2. Mal über deine Antwort (@Quaese) geguckt hab.  Ich hatte zwar nicht $("img:eq(...)") geschrieben, aber ich hatte statt img eine Klasse, die ich dem genierten Element nicht zugewiesen hatte. Hab dem jetzt auch die klasse verpasst und kann es mit :eq() ansprechen. Jetzt sollte es klappen.

Warum ich allerdings bei 
	
	
	



```
$("#projektDetails").index(this)
```
 eine -1 bekomme, weiss ich immernoch nicht - ich forsche weiter.

@jeipack:
Kann das wirklich auch ein CSS-Problem sein? Immerhin geht es um die Reihenfolge im DOM und die ist durch CSS ja nicht änderbar. Sollte sich meine evtl. gefundene Lösung als falsch erweisen, geb ich deinem Einwand eine Chance. 

Gruß Lars


----------



## Quaese (24. Oktober 2013)

Hi,

wenn die Bilder alle die gleiche Breite haben, sollte es wie folgt funktionieren:

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>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(){
    var index = 8;

    $('#insert').on('click', function(evt){
        var neu = $('<div id="projektDetails"><h1>...</h1><p>...</p><img ... /></div>');


        $('#projektContainer img').eq(index).after(neu);
        $('#moreButtons').show();
    });

    $(window).on('resize', function(){
        var winWidth = $(window).width(),
            imgWidth = $('#projektContainer img:first').width(),
            imgPerRow = Math.floor(winWidth/imgWidth),
            line = Math.floor((index+1) / imgPerRow);

        index = line * imgPerRow -1;

        $('#projektContainer').children('img').eq(index).after($('#projektDetails'));
    });
});
</script>
<style>
.left{
  float: left;
}

#projektDetails{
  clear: both;
}
</style>
</head>
<body>
<div id="projektContainer">
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
    <img width="200" height="200" class="left" src="image.jpg" alt="..." />
</div>
<hr style="clear: both;" />
<button id="insert">insert</button>
</body>
</html>
```
Ciao
Quaese


----------



## BoR (24. Oktober 2013)

Es lag tatsächlich an der fehlenden Klasse. Meine anfängliche Idee kann ich nun doch so umsetzen. Danke für die schnellen Hilfen. 

Gruß Lars


----------

