• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[FRAGE] Eltern-Element (div) schließen, neues hinzufügen und dann wieder öffnen

morhinio

New member
Hallo,
ich möchte gerne beim Vorkommen einer bestimmten css-Klasse das Eltern-Element dieses Elementes schließen, ein neues Element hinzufügen und dann das Eltern-Element wieder öffnen. (mit jQuery)

Ausgangssituation
HTML:
<div class="container">
     <p >wwwww</p>
     <p class="check">yyyyyy</p>
     <p >xxxxxx</p>
</div>

Ergebnis soll wie folgt aussehen:
HTML:
<div class="container">
     <p >wwwww</p>
</div>
<div class="container">
     <p class="check">yyyyyy</p>
</div>
<div class="container">
     <p >xxxxxx</p>
</div>

Ich habe es schon mit append, before, wrap, etc. versucht - leider ohne Erfolg. Scheinbar kann ich kein Eltern-Element schließen, sondern nur ein Element umschließen bzw. ein neues hinzufügen.
Ist mein Vorhaben überhaupt möglich?
 
Ist vielleicht unwrap() das, was Du suchst? Etwa so:
Code:
$("#container").children("p").addClass("myp").first().unwrap();
$(".myp").each(function (){$(this).wrap("<div class='container'></div>");})
 
Was meinst du denn genau mit "schließen"?
Ich meine den Container schließen. </div>

Danke für den Hinweis. Bei meinem ersten Beispiel funktioniert es. Möchte ich aber im ersten Container (<div>) 2 Absätze (<p>) haben, funktioniert es nicht, da er jeden Abstz mit einem Container umschließt.

Beispiel:
HTML:
<div class="container">
     <p>xxxxxx</p>
     <p>xxxxxx</p>
     <p class="check">xxxxxx</p>
     <p>xxxxxx</p>
</div>

Momentanes Ergebis
HTML:
<div class="container">
     <p class="myp">xxxxxx</p>
</div>
<div class="container">
     <p class="myp">xxxxxx</p>
</div>
<div class="container">
     <p class="myp">xxxxxx</p>
</div>
<div class="container">
     <p class="myp">xxxxxx</p>
</div>

So hätte ich es gerne
HTML:
<div class="container">
     <p>xxxxxx</p>
     <p>xxxxxx</p>
</div>
<div class="container">
     <p class="check">xxxxxx</p>
</div>
<div class="container">
     <p>xxxxxx</p>
</div>
 
Achso, ok. Dann ist der Sprachgebrauch aber falsch. Du öffnest das nicht und schließt es dann wieder sondern du fügst in das DOM an der Stelle etwas ein, fertig. Es gibt nämlich kein "öffnen" und "schließen" im DOM. Ein Element ist immer vollständig oder das HTML ist kaputt.

Und dein Problem ist mit den DOM Methoden von jQuery ganz einfach lösbar. Schau dir mal die Funktionen .append() und .prepend() an.
 
Genau das ist mein Problem - ich kann nur komplette Elemente hinzufügen. Damit erhalte ich allerdings nicht mein gewünschtes Ergebnis.

Gibt es evtl. eine Alternative zu den DOM Methoden, mit denen es funktionieren könnte?
 
Hallo Steelwheel,
kannst Du mal erklären, wie das das Problem des TO lösen soll?
Hallo Morhinio,
ich bin auch der Meinung, dass es mit den Funktionen, die micdoe genannt hat, geht. Zusätzlich brauchst Du noch die Funktion first(). Im Anschluss an den vorhandenen Code:
1. Erstes p-Element in Variable speichern.
2. Ersten div-Wrapper komplett löschen.
3. Das gespeicherte p-Element vor dem schon vorhandenen im jetzt ersten div-Wrapper einfügen.
 
ich kann nur komplette Elemente hinzufügen. Damit erhalte ich allerdings nicht mein gewünschtes Ergebnis
Darin sehe ich keinen Widerspruch, das gewünschte Ergebnis ist doch das Einfügen kompletter Knoten, in diesem Falle sind es <p>'s
Mal als Ablaufplan in Kurzform:
  • baue die drei neuen gewünschten <div> Kontainer, formatiere sie, setze sie an die gewünschte Stelle
  • bewege die inneren 4 <p>'s in die gewünschten Kontainer (jQuery's .detach() zusammen mit .append())
  • lösche den ursprünglichen <div> Kontainer
Ich habs jetzt nicht gecodet aber das sollte mit 2, max. 3 jQuery Zeilen möglich sein. Es kommt auf die Kompliziertheit der Bedingungen an, nach denen die <p>'s in die neuen Kontainer verschoben werden müssen.
 
Es kann sein, dass der Absatz (p.check) an unterschiedlichen Positionen vorkommt bzw. es zuvor oder danach eine unterschiedliche Anzahl von weiteren Absätzen gibt.

Das ist mein derzeitiger Ansatz:
Edit fiddle - JSFiddle

So sollte es bei einem vorkommen von p.check funktionieren.
Bei mehreren Absätzen mit der Klasse check wird es so allerdings nicht gehen. Da muss ich noch feilen.
 
Hallo morhinio,
kannst Du vielleicht mal erklären, was der Hintergrund bei der ganzen Sache ist? Warum kannst Du die Strukturen nicht gleich so anlegen, wie Du sie brauchst? Kannst Du die Klassen der p-Elemente so anlegen, wie Du es brauchst? Sollen alle p-Elemente, die durch p.check getrennt sind, zusammen gewrappt werden?
 
Zuletzt bearbeitet:
Ich hole mal etwas mehr aus. Meine Beispiele waren etwas vereinfacht dargestellt.

Es handelt sich um bootstrap. (die row und col Container habe ich in meinem Beispiel weggelassen). Der Container wird standardmäßig im Grid (Breite z.B. 1170px) dargestellt.
Ich möchte jetzt allerdings einen bzw. evtl. auch mehrere Absätze mit voller Breite darstellen. Daraus resultiert meine gewünschte Struktur.

Kannst Du die Klassen der p-Elemente so anlegen, wie Du es brauchst?
In meinen Fall kann ich nur die Struktur innerhalb des Containers beeinflussen. Daher mein Ansatz mit der Klasse im p-Element.
Die Anzahl der p-Elemente und die Reihenfolge kann ich festlegen, ist allerdings nicht immer gleich.

Sollen alle p-Elemente, die durch p.check getrennt sind, zusammen gewrappt werden?
Nein, die p-Elemente sollen nicht alle zusammen gwrappt werden. Der grundlegende Aufbau soll erhalten bleiben (wie im JSFiddle Beispiel).
 
Danke für die Erklärung.
Sollen alle p-Elemente, die durch p.check getrennt sind, zusammen gewrappt werden?
Ich meinte nicht, dass sie alle zusammen gewrappt werden sollen, sondern immer nur die, die zusammenhängend zwischen den p.check-Elementen liegen. So wie im Fiddle.
 
Boah, ich kotze ... ich sehe gerade, dass mein Fiddle gar nicht dem entspricht, was es eigentlich war?!?!?!?!?!? Jetzt verstehe ich auch die Frage von Sempervivum, wie es helfen soll. Ich krieg zuviel ... !!! Sorry, das hilft nämlich GAR NICHT!

EDIT: Also das tut mir jetzt echt leid! Das war mit Aufzeigen von console.log() Ausgabe, vorher-nachher, DOM-check (durchzählen erreichbarer Knoten) etc. Fiddle mag mich nicht ... ist nämlich dann klarer Bedienerfehler von mir gewesen. Folgeversionen habe ich nicht lokal - meine Chronik hat auch nur den Link von oben, aber der ist grotesk bis idiotisch falsch. Sorry für die Verwirrung - meine "Lösung" war ohne detach(), wrap() etc.
 
Zuletzt bearbeitet:
Code:
<html>
<head>
  <script type="text/javascript" src="jquery.js"></script>
  <title></title>
  <script>
    $(function(){
      var createCont = function(element)
      {
        var $cont = $("<div class='container'></div>");
        $(element).parent().before($cont);
        return $cont;
      };
      $(".container > [class='check']").each(function(index, element)
      {
        if ($(element).index() > 0)
        {
          var $cont = (!$(element).parent().prev(".container").length || $(element).parent().prev().children("[class='check']").length) ? createCont(element) : $(element).parent().prev();
          $cont.append($(element).parent().children(":lt(" + $(element).index() + ")"));
          if ($(element).parent().children().length > 1)
          {
            createCont(element).append(element);
          }
        }
        else if ($(element).parent().prev().children("[class='check']").length)
        {
          $(element).parent().prev().append(element);
          if ($(element).parent().next(".container").children().length == 0)
          {
            $(element).parent().next(".container").remove();
          }
        }
        else if ($(element).parent().children().length > 1)
        {
          createCont(element).append(element);
        }
      });
    });
  </script>
</head>
<body>
  <div class="container">
    <p>111111</p>
    <p>222222</p>
    <p class="check">33</p>
    <p class="check">44</p>
    <p>555555</p>
    <p class="check">66</p>
    <p>777777</p>
    <p>888888</p>
  </div>
  <div class="container">
    <p>999999</p>
    <p class="check">aa</p>
    <p class="check">bb</p>
    <p>cccccc</p>
    <p class="check">dd</p>
  </div>
  <div class="container">
    <p class="check">ee</p>
    <p>ffffff</p>
    <p class="check">gg</p>
  </div>
</body>
</html>
 
Ich habe mal dieses ausgearbeitet:
Code:
                    var help = $(".container").children("p");
                    help.first().unwrap();
                    help.each(function () {
                        if ($(this).hasClass("check")) {
                            $(".tobewrapped").removeClass("tobewrapped").wrapAll("<div class='container'></div>");
                            $(this).wrap("<div class='container'></div>");
                        } else {
                            $(this).addClass("tobewrapped");
                        }
                    });
                    $(".tobewrapped").removeClass("tobewrapped").wrapAll("<div class='container'></div>");
(Fiddle geht im Moment nicht.)
 
Zuletzt bearbeitet:
Zurück
Oben