1
votes

jquery - Insertion d'un élément toutes les deux boucles

J'essaie d'envelopper un ensemble d'images dans un div toutes les deux boucles. De telle sorte que toutes les deux colonnes bootstrap sont dans des lignes individuelles. par exemple

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
 <div class="container"></div>

Comme vous pouvez le voir dans cet exemple ci-dessous, cela semble fonctionner lorsque vous utilisez du texte.

.row {
min-height:1px;
background:blue;
}

.col-6 {
background:red;
}
var data = ["https://via.placeholder.com/100",
  "https://via.placeholder.com/100",
  "https://via.placeholder.com/100",
  "https://via.placeholder.com/100"
];

var output = $('.container');
var i = 0;
$.each(data, function(index, value) {
  var template = '<div class="col-6"><img src=' + value + '></div>';
  if (i % 2 == 0) {
    output.append('<div class="row">')
  }
  output.append(template)
  i++;
  if (i % 2 == 0) {
    output.append('</div>')
  }
})

Cependant, lorsque j'utilise des divs réels, ils se ferment automatiquement, ce qui donne une structure comme:

<div class="container">

    <div class="row"></div>

    <div class="col-6"><img src="https://via.placeholder.com/100"></div>
    <div class="col-6"><img src="https://via.placeholder.com/100"></div>

    <div class="row"></div>

    <div class="col-6"><img src="https://via.placeholder.com/100"></div>
    <div class="col-6"><img src="https://via.placeholder.com/100"></div>
</div>

Exemple d'extrait:

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container"></div>
var data = ["https://via.placeholder.com/100",
  "https://via.placeholder.com/100",
  "https://via.placeholder.com/100",
  "https://via.placeholder.com/100"
];

var output = $('.container');
var i = 0;
$.each(data, function(index, value) {
  var template = '<div class="col-6"><img src=' + value + '></div>';
  if (i % 2 == 0) {
    output.append('<p>ROW START</p.')
  }
  output.append(template)
  i++;
  if (i % 2 == 0) {
    output.append('<p>ROW END</p>')
  }
})
<div class="row">
  <div class="col-6"><img src=".."></div>
  <div class="col-6"><img src=".."></div>
</div>

Pourquoi les balises div se ferment-elles automatiquement, comment puis-je résoudre ce problème?


5 commentaires

Le DOM n'est pas une chaîne HTML, vous ne regroupez donc pas de balises insérées individuellement. Si vous comptez créer des éléments DOM à partir de chaînes HTML, vous devez créer l'élément entier avant qu'il ne soit ajouté. Si vous essayez de le faire en morceaux, une balise de fermeture manquante sera automatiquement corrigée, et une balise de fermeture isolée sera ignorée comme entrée non valide.


Ajoutez le template avant d'attacher l'élément au DOM.


le template est une chaîne, je ne peux pas y ajouter, ce n'est pas un objet jquery


Faites-le jQuery - $ (template) .


J'ai essayé cela, ne fonctionne toujours pas correctement. N'hésitez pas à donner un exemple de réponse. La raison pour laquelle cela ne fonctionnera pas est en fait le même problème. Je ne peux pas sortir les deux div sans la fermeture automatique de la ligne, que j'ajoute d'abord à la chaîne div


3 Réponses :


1
votes

Le DOM n'est pas une chaîne HTML, vous ne regroupez donc pas de balises insérées individuellement. Si vous comptez créer des éléments DOM à partir de chaînes HTML, vous devez créer l'élément entier avant qu'il ne soit ajouté. Si vous essayez de le faire par morceaux, une balise de fermeture manquante sera automatiquement corrigée et une seule balise de fermeture sera ignorée comme entrée non valide.

À la place, préconstruisez la chaîne entière et ajoutez-la une fois terminée.

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">
  <div>
var data = ["https://via.placeholder.com/100",
  "https://via.placeholder.com/100",
  "https://via.placeholder.com/100",
  "https://via.placeholder.com/100"
];

var html = data.reduce(function(res, value, i) {
  return res +
    (i % 2 === 0 ? '<div class="row">' : "") +
    ('<div class="col-6"><img src=' + value + '></div>') +
    (i % 2 !== 0 ? '</div>' : "");
}, "");

$('.container').append(html);

Cette solution utilise .reduce () , car elle est intégrée à JS, et conçue précisément dans ce but. Le jQuery restant peut également être facilement éliminé, ce qui vous permet de vous libérer de toute abstraction inutile.


3 commentaires

Et j'apprécie vos efforts, mais votre réponse ne semble pas non plus fonctionner.


J'ai transformé votre réponse en un extrait de code, veuillez inspecter la sortie et vous verrez


Désolé, j'avais bâclé la deuxième condition. Aurait dû être i! == 0 .



2
votes

Préparez (créez) le contenu de la chaîne, puis ajoutez à votre sortie. Quelque chose comme ça.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<div class="container"></div>
.row {
  min-height: 1px;
  background: blue;
}

.col-6 {
  background: red;
}
var data = ["https://via.placeholder.com/100",
  "https://via.placeholder.com/100",
  "https://via.placeholder.com/100",
  "https://via.placeholder.com/100"
];

var output = $('.container');
var i = 0;
var content = '';

$.each(data, function(index, value) {
  var template = '<div class="col-6"><img src=' + value + '></div>';
  if (i % 2 == 0) {
    content += '<div class="row">';
  }
  content += template;
  i++;
  if (i % 2 == 0) {
    content += '</div>';
  }
})
output.append(content);


2 commentaires

Notez que cela ne fonctionne qu'avec une longueur paire de données.


Il pourrait être facilement développé en comptant la longueur de l'ensemble de données et en vérifiant si c'est le dernier élément et s'il est impair ou pair, n'est-ce pas?



2
votes
$.each(data, function(index, value) {
  var template = '<div class="col-6"><img src=' + value + '/></div>';
  if (i % 2 == 0) {
    output.append('<div class="row"></div>')
  }
  $(".row").last().append(template)
  i++;
})
Just append template to the last added row.https://jsfiddle.net/zL5phyfq/

1 commentaires

J'aime la simplicité