I have the following structure example:
<div >
<div >Image1</div>
<div >Image2</div>
<div >Image3</div>
</div>
<div >
<div >Banner1</div>
<div >Banner2</div>
<div >Banner3</div>
<div >Banner4</div>
</div>
I want to make a script that will take each banner and placed under each image.
<div >
<div >Image1</div>
<div >Banner1</div>
<div >Image2</div>
<div >Banner2</div>
<div >Image3</div>
<div >Banner3</div>
<div >Banner4</div>
</div>
<div ></div>
Basically there are some images placed one after another and then some banners placed one after another.
Image1 Image2 Image3 Banner1 Banner2 Banner3 Banner4
I need to take each banner and place it under each image so I can have:
Image1 Banner1 Image2 Banner2 Image3 Banner3 Banner4
I cannot change the html to manually placed the banners, I need to use a more advanced script JS and or jquery ..
.content {display:flex; max-width:800px;min-width:300px;gap:20px;margin:auto;}
.main { flex: 70%;}.main2 {max-width:400px;}
.side { flex: 30%; padding:10px;}.img { background:blue;}.banner { background:red;}
.img, .banner { width:100%; min-width:50px; height:50px;display:grid;place-items:center; color: #fff; margin:10px auto;}
<h2>Rearrange content - Place each div (banner) under each image </h2>
<div >
<div >
<div >Image 1</div>
<div >Image 2</div>
<div >Image 3</div>
<div >Image 4</div>
<div >Image 5</div>
<div >Image 6</div>
<p> Multiple DIVs with images ...
<br> ...
</div>
<div >
<div >Banner1</div>
<div >Banner2</div>
<div >Banner3</div>
<div >Banner4</div>
<div >Banner5</div>
<div >Banner6</div>
<div >Banner7</div>
<div >Banner8</div>
<div >Banner9</div>
<div >Banner10</div>
</div>
</div>
<hr>
<h2> This is how it should look </h2>
<div >
<div >Image 1</div>
<div >Banner1</div>
<div >Image 2</div>
<div >Banner2</div>
<div >Image 3</div>
<div >Banner3</div>
<div >Image 4</div>
<div >Banner4</div>
<div >Image 5</div>
<div >Banner5</div>
<div >Image 6</div>
<div >Banner6</div>
<div >Banner7</div>
<div >Banner8</div>
<div >Banner9</div>
<div >Banner10</div>
</div>
CodePudding user response:
To do what you require you can loop through the .banner
elements and use their index to place them underneath the related .img
element by their indexes using insertAfter()
. Something like this:
let $imgs = $('.content .main .img');
$('.content .side .banner').each((i, el) => $(el).insertAfter($imgs[i]));
.content {
display: flex;
max-width: 800px;
min-width: 300px;
gap: 20px;
margin: auto;
}
.main {
flex: 70%;
}
.img,
.banner {
width: 100%;
min-width: 50px;
height: 50px;
display: grid;
place-items: center;
color: #fff;
margin: 10px auto;
}
.img {
background: blue;
}
.banner {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<div >
<div >Image 1</div>
<div >Image 2</div>
<div >Image 3</div>
<div >Image 4</div>
<div >Image 5</div>
<div >Image 6</div>
</div>
<div >
<div >Banner1</div>
<div >Banner2</div>
<div >Banner3</div>
<div >Banner4</div>
<div >Banner5</div>
<div >Banner6</div>
</div>
</div>
CodePudding user response:
You need to loop over the elements and then merge/combine the arrays as you are looping. There are multiple ways this can be done. Here's one way (with comments) that uses reduce
to combine the elements.
If you're starting out with JS, I would suggest using a simple for loop to start off.
When you run the code snippet below, the original will be in Red. Clicking the button will merge the elements, append them, and display them in Green.
Good luck!
// I've wrapped this in a function so I can call it.
function rearrange() {
// First I'm going to query all the divs with 'img' class
// From that, I'll call 'Array.from' to create an array.
const images = Array.from(document.querySelectorAll('.img'));
// Similar to above, but for all the 'banner' divs.
const banners = Array.from(document.querySelectorAll('.banner'));
// This is my loop. I'm using .reduce, but for/while/.forEach/etc
// would all have worked.
// I'm going to loop over the images and push image/banner into
// a new container
const container = images.reduce(function (el, image) {
// get the first "banner" div
const banner = banners.shift();
// append the image div, first
el.appendChild(image);
// if a banner exists, append that
if (banner) {
el.appendChild(banner);
}
// as this is a reducer, i return my accumulator of divs
return el;
}, document.createElement('div'));
// As image/banner could differ in length, push any additional
// banner divs to the container
if (banners.length > 0) {
banners.forEach(banner => container.appendChild(banner));
}
// Add the new class name
container.classList.add('main2');
// Finally, append to body
document.querySelector('.body').appendChild(container);
}
// My event handler to run
document.querySelector('#rearrange').addEventListener('click', rearrange);
.content,
.main2 {
font-family: sans-serif;
line-height: 2;
color: red;
}
.main2 {
color: green;
}
<div >
<button id="rearrange">Click here to re-arrange</button>
<h2>Rearrange content - Place each div (banner) under each image </h2>
<div >
<div >
<div >Image 1</div>
<div >Image 2</div>
<div >Image 3</div>
<div >Image 4</div>
<div >Image 5</div>
<div >Image 6</div>
</div>
<div >
<div >Banner1</div>
<div >Banner2</div>
<div >Banner3</div>
<div >Banner4</div>
<div >Banner5</div>
<div >Banner6</div>
<div >Banner7</div>
<div >Banner8</div>
<div >Banner9</div>
<div >Banner10</div>
</div>
</div>
<h2>Rearranged:</h2>
<hr />
</div>
CodePudding user response:
Well, to answer my own question, it was hard for me since I don't know JS that well.
I managed to make something that also randomizes the banners and I've used jquery.
jQuery("#btn").click(function() {
var cards = jQuery(".side .banner");
for(var i = 0; i < cards.length; i ){
var target = Math.floor(Math.random() * cards.length -1) 1;
var target2 = Math.floor(Math.random() * cards.length -1) 1;
cards.eq(target).before(cards.eq(target2));
}
cards = jQuery(".side .banner");
var images = jQuery(".content.desk .img");
if (cards.length < images.length) {
for (var i=0; i<cards.length; i ) {
images.eq(i).after(cards.eq(i));
}
} else {
for (var i=0; i<images.length; i ) {
images.eq(i).after(cards.eq(i))
}
for (var i=images.length; i<cards.length; i ){
cards.eq(i-1).after(cards.eq(i));
}
}
});
body {
max-width:1250px;
margin:auto;
}
h1, h2, h3, h4 {
text-align:center;
}
.content {
display:flex;
max-width:800px;
min-width:300px;
gap:20px;
margin:auto;
}
.main {
flex: 70%;
}
.side {
flex: 30%;
background: lightblue;
padding:10px;
}
.img {
background:blue;
}
.banner {
background:red;
}
.img, .banner {
width:100%;
min-width:50px;
height:50px;
display:grid;
place-items: center;
color: #fff;
margin:10px auto;
}
<body>
<h1>Rearrange content</h1>
<div >
<div >
<button id="btn">Click to reorder and randomize</button>
<div >Image 1</div>
<div >Image 2</div>
<div >Image 3</div>
<div >Image 4</div>
<div >Image 5</div>
<div >Image 6</div>
<div >Image 7</div>
<div >Image 8</div>
<div >Image 9</div>
<div >Image 10</div>
<div >Image 11</div>
<div >Image 12</div>
<div >Image 13</div>
</div>
<div >
<div >Banner1</div>
<div >Banner2</div>
<div >Banner3</div>
<div >Banner4</div>
<div >Banner5</div>
<div >Banner6</div>
<div >Banner7</div>
<div >Banner8</div>
<div >Banner9</div>
<div >Banner10</div>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
</body>