• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

JQuery: Div-Container "teilen"

blabla333

Mitglied
Ich möchte gerne aus dem hier:

HTML:
<div class="box">
    <div class="content">
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</p>
        <p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
        <p>At vero eos et accusam et justo duo dolores et ea rebum.</p>
    </div>
</div>

Das hier machen:

HTML:
<div class="box">
    <div class="content">
       <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</p>
    </div>

    <div class="box2">
        <div class="content">
            <p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
        </div>
    </div>

    <div class="content">
        <p>At vero eos et accusam et justo duo dolores et ea rebum.</p>
    </div>
</div>

Mein Lösungsansatz ist bislang der, dass ich per wrap schon mal dem betreffenden Paragraph die beiden Container "box2" und "content" verpasse.

Ich weiß aber nicht, wie ich an den darüberliegenden "content" von "box" herangehen kann.
Schließlich muss "content" erst einmal geschlossen werden und nach "box2" wieder neu eröffnet werden! Letzteres aber nur dann, wenn überhaupt noch ein Inhalt folgt. Wenn z.B. oben der dritte Absatz in eine "box2" gepackt werden soll, dann kommt ja nichts mehr danach, so dass hier nur einmal der Container geschlossen werden muss, box2 eingefügt und danach ja auch nur noch das End-Tag von "box" kommt...
 
Werbung:
Hallo,

lass die Divitis sein. Aus deinen Angaben ist nicht zu erkennen, das du dich davon anstecken lassen musst. Und wozu die doppelten (ineinander verschachtelten) div? Die braucht man heute in der Regel gar nicht mehr, da gibt es bessere Lösungen.

Schreib' lieber mal, was du überhaupt erreichen willst. Dann kann dir auch geholfen werden.

Gruss

MrMurphy
 
Eigentlich sind das nicht viele Divs: box, box2 und box3 sind für das Aussehen (Css; jede Ebene sieht anders aus) und die Klasse content brauche ich für einen JS-Editor, welcher hierüber initialisiert wird.
Insofern brauche ich genau diese Struktur. Wie gesagt, mein Problem liegt vor allem, wie ich diese erste Ebene teilen kann...
 
Werbung:
Ich würde da anders rangehen.

Im ersten Schritt die Texte aus den <p> Containern ziehen und zwischenspeichern. Im zweiten Schritt alle obsoleten Container aus dem DOM löschen. Im dritten Schritt neue Container erstellen, ins DOM einfügen und mit den gespeicherten Texten belegen. wrap() und unwrap() brauche ich dazu nicht.
 
Ok, ist eine Überlegung wert. Scheint mir erst einmal sehr aufwändig, aber eigentlich ist es gar nicht so schlecht.
Dann habe ich aber folgendes Problem. Über das externe Editor-Script kann der User den Text markieren, der in die neue Box soll. Ich habe also den neuen Teil in einer Variable. Wie kann ich nun alle anderen Abschnitte abfragen? Bzw. wie frage ich die einzelnen Blöcke überhaupt ab? Da auch img- oder ul-Elemente vorliegen können, würde ich nämlich liebe die p-Elemente insgesamt erfassen und nicht einfach nur den Text daraus.

Im Grunde muss ich doch irgendwie alle Elemente einzeln durchgehen und dann neu zusammensetzen, dh. entscheiden, wo die hin sollen...
 
Was genau willst du abfragen. bzw. wie lautet die Condition?

Und wie lautet das Event, welches die Condition triggert?
 
Werbung:
Hier ist ein Beispiel, was leider so noch nicht funktioniert und wie ich finde auch extrem schlecht gelöst ist - aber leider kann ich es (noch) nicht besser: http://jsfiddle.net/u59qX/4/
Der Button, über den die Funktion aufgerufen wird befindet sich ganz links und hat kein Icon...

Der Hintergrund dazu ist, dass der Container "content" immer als Editor fungieren soll.
Wenn der User nun einen Text markiert, kann er über einen Button diesen Teil in eine eigene Box packen, hierzu dann wieder eine eigene Instanz des Editors. Damit mehrfache Editoren nicht verschachtelt sind, muss ich es eben teilen.
Hört sich jetzt vielleicht etwas kompliziert an, aber bei verschachtelten Konstrukten ergeben sich verschiedenste Probleme.

Der User kann innerhalb der ersten Box mehrere zweite Boxen erstellen und innerhalb der zweiten Box wiederum dritte Boxen (drei Ebenen). Mehr nicht.
 
Wie wäre folgender Ansatz?
Zunächst den ausgewählten Absatz mit .wrap die Container mit den Klassen "box2" und "content" versorgen.
Anschließend mit .each alle p-Elemente durchgehen -> Prüfen, welcher parent vorliegt (box1, box2 oder box3) -> In dieser Schleife dann jedes Element in einen neuen DOM schreiben:

Code:
     jQuery(html).wrapAll('<div class="'box2'"><div class="content"></div></div>');
        $( "p" ).each(function( index ) {
            if ( jQuery(this).closest('.box3').length ) { console.log( "3: " + $(this).html() ); }
            else if ( jQuery(this).closest('.box2').length ) { console.log( "2: " + $(this).html() ); }
            else if ( jQuery(this).closest('.box1').length ) { console.log( "1: " + $(this).html() ); }
            else { console.log( "0: " + $(this).html() ); }
        });

Das Problem, das ich sehe: Es funktioniert nur mit p-Elementen. Wenn jetzt ein img-Element dabei ist, gibt es schon Probleme...
 
Zuletzt bearbeitet:
Ist mir jetzt zu spät, um mich da reinzudenken, aber wo $(this).html(), $(this).text() und $(this).val() Inhalte zurückliefern, lassen sich mit event.target.nodeName die wrappenden HTML Container abfragen und für die Funktion dynamisieren.
 
Werbung:
Ich habe mein Script jetzt so weit fertig und es scheint zu funktionieren. Kannst du mir helfen das hier zu optimieren? Ich denke es ist leider etwas zu umständlich geworden, oder?

Code:
      var aktuell = -1;
        if ( $("#ausgabe").length ) { $( "#ausgabe" ).empty(); }
        else { $('body').append('<div id="ausgabe">'); } // Ist nur ein Ausgabe-Container

        $( "p" ).each(function( index ) { // Es werden alle p-Elemente neu sortiert
            if ( $(this).closest('.box3').length ) {  // Alle hintereinander folgenden Elemente, die in box3 sind, werden in die neue  box3 gepackt
                if (aktuell != 3) {
                    $('#ausgabe').append('<div class="box3">');
                    $('.box1:last').append('<div class="content">')
                }
                $('.box1 .content:last').append($(this).html());
                aktuell = 3; }
            else if ( $(this).closest('.box2').length ) {   // Alle hintereinander folgenden Elemente, die in box2 sind, werden in die neue  box2 gepackt
                if (aktuell != 2) {
                    $('#ausgabe').append('<div class="box2">');
                    $('.box1:last').append('<div class="content">')
                }
                $('.box1 .content:last').append($(this).html());
                aktuell = 2;}
            else if ( $(this).closest('.box').length ) {  // Alle hintereinander folgenden Elemente, die in box sind, werden in die neue  box gepackt
                if (aktuell != 1) {
                    $('#ausgabe').append('<div class="box1">');
                    $('.box1:last').append('<div class="content">')
                }
                $('.box1 .content:last').append($(this).html());
                aktuell = 1;    
            }
            else {
                if (aktuell != 0) {
                    $('#ausgabe').append('<div class="box0">');
                    $('.box0:last').append('<div class="content">')
                }
                $('.box0 .content:last').append($(this).html());
                aktuell = 0; }
        });
 
Das Script produziert einen anderen Code als deine HTML-Ausgabe im ersten Beitrag. Ich weiß nicht, was genau du willst. Das (jeweils) dritte Child soll um eine Ebene tiefer in der DOM Hierarchie verschoben werden?

Außerdem sind die Redundanzen und hartcodierten Zahlen nicht notwendig. each() liefert bereits drei Werte zurück, die sich dynamisch verarbeiten lassen. NodeType, NodeIndex und NodeContent.
HTML:
<div class="box">
    <div class="content">
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</p>
        <p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
        <p>At vero eos et accusam et justo duo dolores et ea rebum.</p>
    </div>
</div>

$('p').each(function(index, value) {
  childNodeNr = index;
  childNodeType = '<' + value.nodeName.toLowerCase() + '>';
  childContent = $(this).text();
  console.log('child nr: ' + childNodeNr + ' - HTML tag: ' + childNodeType + ' - inhalt: ' + $(this).text() );
});
 
Danke. Aber ich brauche doch auch das parent-Element, um zu wissen, zu welcher Box das jetzt nun gehört. Zumindest war das mein Ansatz. Und dann eben neu ordnen - muss nochmal nach dem Unterschied schauen; irgendwas habe ich falsch gemacht.

Habe dann aber noch das Problem, dass bei meiner Lösung zwei aufeinanderfolgende box2 zu einer zusammengefasst werden. Das sollte nicht so sein.
Ich gehe ja jedes Element durch und prüfe, ob nun eine andere Ebene vorliegt. Wenn nein, dann kommt es mit in die aktuelle Box. Wenn ja, wird eine neue begonnen.

HTML:
<div class="box2">
    <div class="content">
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</p>
        <p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
        <p>At vero eos et accusam et justo duo dolores et ea rebum.</p>
    </div>
</div>
<div class="box2">
    <div class="content">
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</p>
        <p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
        <p>At vero eos et accusam et justo duo dolores et ea rebum.</p>
    </div>
</div>

In diesem Fall sollten beide box2 so bestehen bleiben. Bei meiner Lösung würden alle p-Elemente in eine box2 gepackt, da alle Elemente den gleichen parent haben.
 
Werbung:
Danke. Aber ich brauche doch auch das parent-Element, um zu wissen, zu welcher Box das jetzt nun gehört.

Dann frage das doch ab.
Code:
<div class="box99">
  <div class="content">
    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</p>
  </div>
</div>

// 99
$('p').closest("[class*=box]").prop('class').substr(3);
 
Super. Danke. Funktioniert natürlich nicht, sobald noch andere Klassen dazukommen (z.B. <div class="box99 irgendwas"></div>)

Und die letzte Sache: Gibt es eine Methode die beiden Eltern-Elemente zu unterscheiden? Ich muss eben noch das Beispiel mit den beiden Boxen mit gleicher Klasse (direkt hintereinander) lösen.
Wollte es eigentlich handhaben, dass ich jedes p-Element durchgehe, prüfe, ob parent eine box-Klasse hat und gleichzeitig prüfen, ob sich dieses parent geändert hat, d.h. ob es das gleiche Element ist. Wäre einfach, wenn die div's z.B. eine ID hätte ,dann würde ich einfach alle p-Elemente durchgehen und sobald sich die ID der parent-box ändert, weiß ich, dass eine neue Box vorliegen muss.

Jetzt sind aber beide nicht zu unterscheiden (außer an der Position). Das müsste ich doch auch irgendwie ermitteln können, oder?
 
Super. Danke. Funktioniert natürlich nicht, sobald noch andere Klassen dazukommen (z.B. <div class="box99 irgendwas"></div>)

Dann musst du den String mit den zurückgelieferten CSS Klassen durchsuchen.
Code:
<div class="irgendwas weitereklasse box99 nochneklasse">

var getBoxClass = function() {
  var getClasses = $('p').closest("[class*=box]").prop('class'),
      obj = getClasses.split(" ");
  for ( key in obj) {
    if ( obj.hasOwnProperty(key) ) {
      if ( obj[key].search('box') > -1 ) {
        return obj[key].substr(3);
      }
    }
  }
};

// 99
var boxNr =  getBoxClass();

Und die letzte Sache: Gibt es eine Methode die beiden Eltern-Elemente zu unterscheiden? Ich muss eben noch das Beispiel mit den beiden Boxen mit gleicher Klasse (direkt hintereinander) lösen.
Mit parent() durchs DOM hangeln anstatt closest() zu verwenden.

Wenn ich mich jetzt noch weiter damit beschäftigen soll, kann ich es auch gleich selber schreiben. Dazu müsstest du es aber in die Jobbörse stellen, und außerdem habe ich am WE keine Zeit.
 
Zuletzt bearbeitet:
Werbung:
Ok, danke sehr. Ich habe den letzten Teil damit gelöst, dass ich closest() und prev() verwende. Funktioniert super.
 
Zurück
Oben