11521 sujets

JavaScript, DOM et API Web HTML5

Modérateur
Bonjour,

Voici le formatage de la portion de page que je souhaite modifier :
<div class="tabs">

<h2>Titre</h2>
<h3>Sous-titre</h3>
  <p>blablabla</p>
  <ul>
    <li>blablabla</li>
    <li>blablabla</li>
  </ul>

<h2>Titre 2</h2>
  <p>blablabla</p>
  <p>blablabla</p>

<h2>Titre 3</h2>
  <ul>
    <li>blablabla</li>
    <li>blablabla</li>
  </ul>

</div><!-- end .tabs -->


Je souhaiterais dynamiquement ajouter des balises, des class et id à ces éléments de façon à obtenir le formatage suivant :
<div class="tabs">

<h2 class="h2_01">Titre</h2>
<div id="content_01">
<h3>Sous-titre</h3>
  <p>blablabla</p>
  <ul>
    <li>blablabla</li>
    <li>blablabla</li>
  </ul>
</div>

<h2 class="h2_02">Titre 2</h2>
<div id="content_02">
  <p>blablabla</p>
  <p>blablabla</p>
</div>

<h2 class="h2_03">Titre 3</h2>
<div id="content_03">
  <ul>
    <li>blablabla</li>
    <li>blablabla</li>
  </ul>
</div>

</div><!-- end .tabs -->


Cette structure peut se répéter plusieurs fois (dans les div de class .tabs). Le jQuery que j'utilise et qui ne fonctionne pas :
if (jQuery(".tabs").length > 0) {
    jQuery(".tabs").each(function(tabInd) {
        /* content wrapping with id and class to h2 */
        jQuery(".tabs h2").after(function(contInd) {
            jQuery(this).addClass('h2_' + tabInd + contInd);
            return '<div id="content_' + tabInd + contInd + '">';
        });
        jQuery(".tabs h2").before(function(contInd) {
            if(contInd != 0) {
                return '</div>';
            }
        });
    });
  } // end if tabs exists


Le résultat (pas souhaité) que j'obtiens :
<div class="tabs">

<h2 class="h2_01">Titre</h2>
<div id="content_01"></div>
<h3>Sous-titre</h3>
  <p>blablabla</p>
  <ul>
    <li>blablabla</li>
    <li>blablabla</li>
  </ul>

<h2 class="h2_02">Titre 2</h2>
<div id="content_02"></div>
  <p>blablabla</p>
  <p>blablabla</p>


<h2 class="h2_03">Titre 3</h2>
<div id="content_03"></div>
  <ul>
    <li>blablabla</li>
    <li>blablabla</li>
  </ul>

</div><!-- end .tabs -->


Comme vous pouvez le constater en insérant après le h2 <div id="content_03">, il ajoute automatiquement le </div>. Le </div> que je souhaitait ajouter avant le h2 (s'il n'est pas le premier) n'apparait pas.

Merci d'avance pour votre aide. Smiley smile
Modifié par jojaba (17 Sep 2016 - 10:09)
Bonjour,
Il faut créer et traiter la div que tu veux ajouter comme un élément du DOM et non comme une chaîne.
Voici un exemple qui fonctionne à peu près comme tu veux (au formatage de l'index près), il crée une div après chaque h2, puis ajoute chaque élément qui suit à cette div (en changeant ainsi le parent), jusqu'au prochain h2 :

$(".tabs h2").each(function(idx){
  var $this=$(this);
  $this.addClass('h2_'+idx);
  var div=$('<div id="content_'+idx+'">');
  $this.after(div);
  div.nextUntil("h2").appendTo(div);
});
Modérateur
Merci pour ta réponse Seven tears.

Avant de voir ta réponse, j'ai également trouvé une solution, j'utilise nextUntil() également, mais j'ai opté pour la fonction wrapAll() pour ajouter le div Smiley cligne :
if (jQuery(".tabs").length > 0) {
    jQuery(".tabs").each(function(tabInd) {
        /* content wrapping with id and class to h2 */
        jQuery(".tabs h2").each(function(contInd) {
            jQuery(this).addClass('h2_' + tabInd + contInd);
            jQuery(this).nextUntil("h2").wrapAll('<div id="content_' + tabInd + contInd + '"></div>');
        });
    });
  } // end if tabs exists

Je ne connaissais pas la fonction nextUntil(), très pratique dans mon cas. A noter que pour le dernier élément traité (le dernier h2), cela ne semble pas poser de problème qu'il n'y ait pas de h2 qui permette de limiter la sélection, la fermeture du div de class .tabs semble faire l'affaire.