Loop a click event function on "animationend" - javascript

I have a question on how to loop a click event itself on animation end
I have 3 pictures i want to rotate on click with an order :
first click on first picture-> first picture rotates,
second click on second picture-> second picture rotates,
third click on third picture-> third picture rotates
the add event listener is the same so i'm trying to loop the function on itself with myEndFunction() but it seems to not be alright
On second click the second picture is moving but i still have to click on first picture
here is the html (very classic one):
<body>
<img id ="first" src= "https://i.ibb.co/bPWLLjV/bookermini.png" alt="booker">
<img id ="second" src= "https://i.ibb.co/KKKqrBp/bobafettmini.png" alt="boba">
<img id ="third" src= "https://i.ibb.co/2yXfmvJ/hommemini.png" alt="joxer">
</body>
here is the css (moving part):
.move {
position : relative;
animation: mymove 1s ;
}
#keyframes mymove {
100%{transform: rotate(360deg); }
}
here is the js code :
var x = document.getElementById("first");
x.addEventListener('click', event => {
x.classList.add("move");
x.addEventListener("webkitAnimationEnd", myEndFunction);
x.addEventListener("animationend", myEndFunction);
function myEndFunction() {
x = document.getElementById("second");
}
});
here is a codepen if you want to try : https://codepen.io/minise/pen/vYGpqJZ
plz i need your help !

It seem that you are using an #id selector which returns always the first occurrence, and stops.
My suggestion would be, to use class identifiers instead and reuse your action function.
var version1 = function () {
// get all containers that has the class rotate-me
var rotateMe = document.querySelectorAll('.version-1 .rotate-me');
// define animation duration, this is better than css animationend
var animationDuration = 1000; // milliseconds
// recursive animation sequence
var startSequence = function (classname, items) {
var [first, ...rest] = items;
first.classList.add('rotate');
setTimeout(function () {
if (rest.length > 0) {
startSequence(classname, rest)
}
}, animationDuration);
};
// click handle that starts the sequence
var handleClick = function () {
startSequence('rotate', rotateMe);
};
// check if one rotateMe was matched
if (rotateMe.length > 0) {
// add you action callback to the first match
rotateMe[0].addEventListener('click', handleClick);
}
}
// this version is blocking click before previeous element was clicked
var version2 = function () {
// get all containers that has the class rotate-me
var rotateMe = document.querySelectorAll('.version-2 .rotate-me');
// define animation duration, this is better than css animationend
var animationDuration = 1000; // milliseconds
// active index
var activeElement = 0;
// click handle that starts the sequence
var handleClick = function (index, item) {
if (index === activeElement) {
item.classList.add('rotate');
activeElement += 1;
}
};
for (var i = 0, l = rotateMe.length; i < l; i += 1) {
// add you action callback to the first match
rotateMe[i].addEventListener('click', (function (index, item) {
return function () {
handleClick(index, item);
};
})(i, rotateMe[i]));
}
}
window.onload = function() {
version1();
version2();
}
.wrapper {
display: flex;
}
.rotate-me {
border-radius: 50%;
overflow: hidden;
font-size: 0;
}
.rotate-me:first-child {
cursor: pointer;
}
.rotate-me.rotate {
cursor: initial;
}
.rotate-me.rotate {
transition: transform 1s;
transform: rotate(360deg);
}
<h2>Version 1</h2>
<div class="wrapper version-1">
<div class="rotate-me">
<img src="http://placekitten.com/150/150" alt="kitten placeholder">
</div>
<div class="rotate-me">
<img src="http://placekitten.com/150/150" alt="kitten placeholder">
</div>
<div class="rotate-me">
<img src="http://placekitten.com/150/150" alt="kitten placeholder">
</div>
<div class="rotate-me">
<img src="http://placekitten.com/150/150" alt="kitten placeholder">
</div>
</div>
<h2>Version 2</h2>
<div class="wrapper version-2">
<div class="rotate-me">
<img src="http://placekitten.com/150/150" alt="kitten placeholder">
</div>
<div class="rotate-me">
<img src="http://placekitten.com/150/150" alt="kitten placeholder">
</div>
<div class="rotate-me">
<img src="http://placekitten.com/150/150" alt="kitten placeholder">
</div>
<div class="rotate-me">
<img src="http://placekitten.com/150/150" alt="kitten placeholder">
</div>
</div>

var x = document.getElementById("first");x.addEventListener('click', event => {
x.classList.add("move");
x.addEventListener("webkitAnimationEnd",myEndFunction);
x.addEventListener("animationend",myEndFunction);});
var y = document.getElementById("second");y.addEventListener('click', event => {
y.classList.add("move");
y.addEventListener("webkitAnimationEnd",myEndFunction);
y.addEventListener("animationend",myEndFunction);});
Is this some thing what u are asking for?/

Well might has well put the event listener to the picture itself.
So you know what to rotate.
Yeah even a div can have an event listener.
Query for the div. add an event listener that onclick the animationPlayState should be running. Else by default put it has paused in css.

Related

Animation and transition property with setTimeout() function

I'm fairly new to JS, and I'm trying to make a simple text slide animation. However, when the animation event is activated the first time, the transition property doesn't apply. Every time after that it works fine.
So I'm struggling with the first execution of the slide animation.
Here is the code:
function slide_animation(direction){
// Init
let text = document.querySelector(".story .box .right-part .text");
let text_html = text.innerHTML;
let text_slide = [
"Text n°1",
'Text n°2',
'Text n°3'
];
let current_slide = 0;
// Looking for the current_slide
for(let i=0;i<text_slide.length;i++){
if (text_slide[i]==text_html){current_slide = i};
}
// Calculating the next slide position
if (direction=='right'){
if (current_slide >= text_slide.length-1){
current_slide = 0;
}
else {current_slide+=1;}
}
else {
if (current_slide <= 0){
current_slide = text_slide.length-1;
}
else {
current_slide = current_slide-=1;
}
}
// Animation
setTimeout(()=>{
text.style.transition = '0.5s';
text.style.opacity = 0;
text.style.left = '100px';
},250);
setTimeout(()=>{
text.innerHTML = text_slide[current_slide];
text.style.opacity = 1;
text.style.left = '0px';
},750)
}
.story .box .right-part .text-container .text {
line-height: 1.25;
position: relative;
}
<div class="box">
<div class="left-part">
<div class="text-container">
<p class="text">
<span class="text-padding fontsize-md">----</span>
</p>
</div>
<div class="buttons-container">
<button class="backward" onclick="slide_animation('left')"></button>
<button class="forward" onclick="slide_animation('right')"></button>
</div>
</div>
<div class="right-part">
<div class="text-container">
<p class="text fontsize-sm">Text n°1</p>
</div>
</div>
</div>
Anyway , it is fixed. I added another setTimeOut that did nothing really useful on the text , i placed it just before the others setTimeOut and it seems to work out properly.
Here is what is inserted :
setTimeout(()=>{
text.style.left=0;
},0)

Remove one image after another when onclick

i have a div that contains 5 of the same image. i'm trying to make a button that can make one of the images disappear one after another when onclick. i've tried the style.visibility but it makes them all disappear together. This is my code
document.getElementById("btn1").onclick = function() {
document.getElementById("output").style.visibility = "hidden";
}
<input id="btn1" type="button" value="Click me" onclick="onClick1()" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div id="output">
<img src="/images/person1.jpg">
<img src="/images/person1.jpg">
<img src="/images/person1.jpg">
<img src="/images/person1.jpg">
<img src="/images/person1.jpg">
</div>
You are targeting the image container and then hiding it so all the images disappear at once.
It's not really clear from your question whether you want to click the button once and have the images disappear, or to click the button repeatedly and have one image disappear on each click. This solution answers the first problem.
If you want to hide the images one-by-one you're going to need to use setInterval or setTimeout to manage that. In this example I've used setTimeout.
document.getElementById('btn1').onclick = function() {
// Get all the images
const images = Array.from(document.querySelectorAll('#output img'));
// Loop over the images
function loop(images) {
// If there are images left remove the first one,
// hide it, and then call the function again with the
// reduced image array until all images are gone.
if (images.length) {
const image = images.shift();
image.style.visibility = 'hidden';
setTimeout(loop, 1000, images);
}
}
loop(images);
}
<input id="btn1" type="button" value="Click me" onclick="onClick1()" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div id="output">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
</div>
Additional documentation
shift
setTimeout
Array.from
If you want to make the images disappear on each click, cache the images, and return a function that the listener calls when you click the button.
const button = document.getElementById('btn1')
button.addEventListener('click', handleClick(), false);
// Cache the image elements, and then return a new
// function to your listener that removes an image on each click
function handleClick() {
const images = Array.from(document.querySelectorAll('#output img'));
return function() {
if (images.length) {
const image = images.shift();
image.style.visibility = 'hidden';
}
}
}
<input id="btn1" type="button" value="Click me" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div id="output">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
<img src="https://dummyimage.com/30x30/000/fff">
</div>
You should give id's to image tag instead of parent div.
Created variable which which will work as a counter.
On each click increase counter and hide the specific image tag.
Your code will look like:
let imageToDelete = 1;
document.getElementById("btn1").onclick = function() {
document.getElementById("image_" + imageToDelete).style.visibility = "hidden";
imageToDelete++;
}
<input id="btn1" type="button" value="Click me" onclick="onClick1()" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div>
<img id="image_1" src="/images/person1.jpg">
<img id="image_2" src="/images/person1.jpg">
<img id="image_3" src="/images/person1.jpg">
<img id="image_4" src="/images/person1.jpg">
<img id="image_5" src="/images/person1.jpg">
</div>
With that script, all you are doing is hiding the parent of all the images, which results in all the images "seemingly disappearing" at once. You have to remove each separately to achieve your desired result.
const RemoveImage = Event => {
const Target = Event.target;
const ImgPos = Target.getAttribute("data-remove");
const Selector = `#image-parent > img:${ImgPos}-of-type`;
const ImgToRemove = document.querySelector(Selector);
if(!ImgToRemove) return false;
ImgToRemove.parentElement.removeChild(ImgToRemove);
return true;
};
const Buttons = document.querySelectorAll("button[data-remove]");
Buttons.forEach(btn => btn.addEventListener("click", RemoveImage));
#image-parent > img:hover {
filter: brightness(92%);
}
#first {outline: 2px solid #a00;}
#last {outline: 2px solid #0a0;}
<div id="image-parent">
<img src="https://via.placeholder.com/70" id="first">
<img src="https://via.placeholder.com/70">
<img src="https://via.placeholder.com/70">
<img src="https://via.placeholder.com/70" id="last">
</div>
<button data-remove="first">Remove first img</button>
<button data-remove="last">Remove last img</button>
If you don't want the images to be removed fully, but rather just hidden:
Rreplce the line ImgToRemove.parentElement.removeChild(ImgToRemove); with something like ImgToRemove.classList.add("hidden-by-css");
Then declare this CSS class with opacity: 0; pointer-events: none;.
We know manipulating HTML DOM is not popular option. But this will work with your problem.
document.getElementById("btn1").onclick = function() {
let imageNode = document.getElementById("output").getElementsByTagName('img')[0];
imageNode.parentNode.removeChild(imageNode)
}
I have found that using the queue() and dequeue() methods from jQuery library is a very good option for resolving this step by step scenarios. This is the stated description of this in the official page:
"Queues allow a sequence of actions to be called on an element asynchronously, without halting program execution. "
I will leave an brief example of how I have implemented it in the past:
$('#anchoredToElement')
.queue("steps", function (next) {
console.log("Step 1");
//In case you want to hold the execution for a bit depending on the scenario you're running
setTimeout(function () { console.log("Action within timeout") }, 500);
next();
})
.queue("steps", function (next) {
console.log("Step 2");
setTimeout(function () {
//Execution example
UploadFile(fileUpload))
}, 500);
next();
})
.dequeue("steps");
Here an example of how I think the logic could be for your needs:
var removeImage = function (index) {
//Logic here to remove image within div according to passed index
};
var index = 0;
$('#output')
.queue("steps", function (next) {
console.log("Remove Image 1");
setTimeout(function () { removeImage(index); }, 250);
index++;
next();
})
.queue("steps", function (next) {
console.log("Remove Image 2");
setTimeout(function () { removeImage(index); }, 250);
index++;
next();
})
.queue("steps", function (next) {
console.log("Remove Image 3");
setTimeout(function () { removeImage(index); }, 250);
index++;
next();
})
.queue("steps", function (next) {
console.log("Remove Image 4");
setTimeout(function () { removeImage(index); }, 250);
index++;
next();
})
.queue("steps", function (next) {
console.log("Remove Image 5");
setTimeout(function () { removeImage(index); }, 250);
index++;
next();
})
.dequeue("steps");
Of course you can improve the JS code as I was just focusing on the step by step process.
This is just a first glance of how $.queue can help you to achieve the step by step process. I recommend to go check the documentation to learn the details and so apply it to your logic as needed.

How do I count divs clicked using an event listener in javascript

I'm trying the count the total number of divs clicked and exactly which ones were clicked. I'm using an event listener because the onclick is already used. Let me clarify a bit more, first, here's my code:
<div class="wrapper">
<div class="square" onclick="classList.toggle('selected')">1</div>
<div class="square" onclick="classList.toggle('selected')">2</div>
<div class="square" onclick="classList.toggle('selected')">3</div>
</div>
<div id="dis"></div>
.selected {
background: white;
}
var numClicked = document.querySelectorAll('.wrapper');
numClicked.forEach(numClicked =>
numClicked.addEventListener('click', clickedDivs)
)
function clickedDivs () {
i = 0;
numClicked.forEach(numClicked =>
i++
var x = document.getElementById("dis");
x.innerHTML = "Squares selected: " + i;
}
What I'm trying to do with my javascript is count how many divs are selected. I'm also trying to tell exactly where ones were clicked. Let's say 1 and 2 were clicked, how do I find those were clicked and total number of divs clicked using js?
What you are doing wrong here is:
You are initialising i within the onClick event fn. which will always reset the value to 0 when ever the div will be clicked.
you are not storing anywhere which div is clicked
You are adding you'r listener on wrapper instead of .square (if you are not trying to get the value of clicked wrappers instead of clicked square)
So you can modify you'r javascript like this
<style>
.square{width: 100px; height: 100px; background: grey;}
.selected {
background: white;
}
</style>
<div class="wrapper">
<div class="square" onclick="classList.toggle('selected')">1</div>
<div class="square" onclick="classList.toggle('selected')">2</div>
<div class="square" onclick="classList.toggle('selected')">3</div>
</div>
<div id="dis"></div>
<script>
var numClicked = document.querySelectorAll('.square');
numClicked.forEach(numClick => {
numClick.addEventListener('click', clickedDivs)
}
)
var itemsClicked = [] //to store which div is clicked
function clickedDivs (e) {
var value = e.target.innerHTML;
//edit
if(itemsClicked.indexOf(value) != -1) itemsClicked.splice(itemsClicked.indexOf(value), 1)
else
itemsClicked.push(value);
var x = document.getElementById("dis");
x.innerHTML = "Squares selected: " + itemsClicked.join(",");
}
</script>
edit:
added to code to remove data from the list if already exist.
Rather than attach a handler to each div, you can use 1 window event listener. Give each clickable div an id that contains "clickable" so the event listener can filter out divs you aren't tracking. When you first click a tracked div, set its id as a key within a global object and assign 1 as the value; on additional clicks, increase value by 1.
const clicks = {};
window.addEventListener("click", (e)=> {
const id = e.target.id;
if(!id.includes("clickable"))return;
clicks[id]? clicks[id] += 1 : clicks[id] = 1;
console.log(clicks);
},)
<div class="wrapper">
<div id="clickable1" class="square">1</div>
<div id="clickable2" class="square">2</div>
<div id="clickable3" class="square">3</div>
</div>
My solution, I haven't tested it yet, test it and tell me how we adjusted it.
<div class="wrapper">
<div class="square" id="d-1">1</div>
<div class="square" id="d-2">2</div>
<div class="square" id="d-3">3</div>
</div>
<div id="result"></div>
var count = [];
var wrappers = document.querySelectorAll('.wrapper');
wrappers.forEach(square => square.addEventListener('click',() => onClickwrapperSquare(square.id));
function onClickwrapperSquare(id) {
var result = document.getElementById('result');
if(count.indexOf(id) == -1){
count.push(id);
}else{
count = count.slice(count.indexOf(id)+ 1);
}
result.innerHTML = `Squares selected: ${count.length}`;
}
This can be simply achieved by jQuery.
var count;
$(".square").click(function (){
count = count+1;
$("#dis").html(count);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class=square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>
<div id="dis"></div>

Showing an element for 5 seconds, then hide and show next element

This is what I've tried so far, but it just shows all the elements at once:
i1 = document.getElementById('img_1');
i2 = document.getElementById('img_2');
i3 = document.getElementById('img_3');
i4 = document.getElementById('img_4');
i5 = document.getElementById('img_5');
myarr = [i1,i2,i3,i4,i5];
for (i=0; i<myarr.length;i++) {
$(myarr[i]).show().delay(5000).fadeOut();
}
I assume you are trying to achieve an endless loop.
I think you should use interval in that case, and do fadeOut/fadeIn of elements.
i1 = document.getElementById('img_1');
i2 = document.getElementById('img_2');
i3 = document.getElementById('img_3');
i4 = document.getElementById('img_4');
i5 = document.getElementById('img_5');
let myarr = [i1, i2, i3, i4, i5];
let active = 1;
setInterval(() => {
$(myarr[active - 1]).fadeOut(500)
if (active >= myarr.length) {
active = 0
}
setTimeout(() => {
$(myarr[active]).fadeIn(500);
active = active + 1;
}, 500)
}, 5000)
What this does, is updates elements every 5 sec to next element, if it reached the end, it resets it to zero.
Checkout this fiddle
You can use async and await.
Another this you can improve is that. You can add same class to all images you want to show in series. If you want to select all by id you can use Attribute Selectors.
const myarr = document.querySelectorAll('img[id^=img]');
I have used same class rather than id
const arr = [...document.querySelectorAll('.test')];
(async function(){
for (let i=0; i<arr.length;i++) {
await new Promise(res => {
setTimeout(() => {
$(arr[i]).show().fadeOut();
res();
},2000)
})
}
})()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test">Test 1</div>
<div class="test">Test 2</div>
<div class="test">Test 3</div>
let count = 1;
setInterval(()=>{
document.querySelectorAll("*[id*='img_']").forEach((elem)=> elem.style.display="none");
document.getElementById(`img_${count}`).style.display="";
if(count<4) count++;
else count = 1;
},1000)
<div id="img_1">Image 1</div>
<div id="img_2" style="display:none">Image 2</div>
<div id="img_3" style="display:none">Image 3</div>
<div id="img_4" style="display:none">Image 4</div>
Vanilla Javascript solution!
You forgot to show your element after fadeOut. Here you can achieve it:
// show first element
$('img').eq(0).show();
$('img').each(function () {
// your delay
$('img').delay(5000).fadeOut();
// make sure next element is image
if ($(this).next()[0].tagName === 'IMG') {
// show next element
$(this).next().fadeIn();
}
});
img {
display: none;
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img src="https://picsum.photos/id/5/50" />
<img src="https://picsum.photos/id/10/50" />
<img src="https://picsum.photos/id/30/50" />
<img src="https://picsum.photos/id/0/50" />
<img src="https://picsum.photos/id/150/50" />
<img src="https://picsum.photos/id/1000/50" />
var basicVal =0;
$(document).ready(function(){
$('.wrapper img').eq( basicVal ).show();
var setTime =setInterval(function(){
if( basicVal < $('.wrapper img').length - 1){
$('.wrapper img').eq(basicVal ).hide();
basicVal++;
$('.wrapper img').eq(basicVal).show();
}else{
clearTimeout(setTime);
}
console.log();
}, 5000);
});
.wrapper{
width: 100%;
float: left;
}
.wrapper img{
width: 50%;
height: 300px;
object-fit: cover;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<img src="https://images.pexels.com/photos/34950/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500" alt="">
<img src="http://www.desktopwallpaperhd.net/wallpapers/0/4/landscapes-wallpaper-fengguangbizhi-fengjingbizhi-picture-image-1316.jpg" alt="">
<img src="http://trustbanksuriname.com/wp-content/uploads/2019/04/pony-picture-guide-to-native-pony-breeds-little-pony-cartoon-pictures.jpg" alt="">
<img src="https://www.bigfoto.com/stones-background.jpg" alt="">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQulscf1nNOpaI1tElZgKTTSAl_ZcL_i1VwLDojgKzqjSTMofsqPw" alt="">
</div>
check this out I use some little bit of jquery and setInterval function to change in every 5000ms
You may use setTimeout for achieving this effect.
<div id="container">
<div class="block" id="img_1"></div>
<div class="block" id="img_2"></div>
<div class="block" id="img_3"></div>
<div class="block" id="img_4"></div>
<div class="block" id="img_5"></div>
</div>
.block{
width:100px;
height:100px;
display: inline-block;
margin:10px;
background: lightblue;
visibility: hidden;
}
And then,
$('.block').each(function(index, value) {
setTimeout(function() {
$(value).css("visibility", "visible");
$(value).show().delay(1000).fadeOut();
}, 2000 * (index + 1));
});

Insert div on next line when element is clicked

I am trying to make something similar to what you find in google images. When a picture is clicked, a div with the image appears on the next line over the other images that is under the clicked one.
I have a set of divs with float:left and position:relative. They have different widths. When i click on a div i want a new full width div to appear on the next line. The divs under the clicked one should be bushed down under the full width one.
I tried to do this by looping through the divs and compare the position of the divs to the clicked one like this:
$(".Wrapper").on("click", ".testDivs", function () {
var thisTop = $(this).position().top;
$(".testDivs").each(function(i, obj) {
var otherTop = $(obj).position().top;
if(thisTop < otherTop){
$(".fullWidthDiv").insertBefore(obj);
return;
}
});
});
This doesn't work and I don't really know how I should do this. Any tips/solutions?
This requires a lot of information to explain. So I'd rather suggest reading a blog post on this topic.Hope this will help you.
https://www.sitepoint.com/recreating-google-images-search-layout-css/
Here is a way to achieve that. It will not keep scroll position but that would be another easy fix.
<div class="wrapper">
<div class="row1 row">
<div class="img1 img"></div>
<div class="img2 img"></div>
<div class="img3 img"></div>
</div>
<div class="row2 row">
<div class="img1 img"></div>
<div class="img2 img"></div>
<div class="img3 img"></div>
</div>
<div class="row3 row">
<div class="img1 img"></div>
<div class="img2 img"></div>
<div class="img3 img"></div>
</div>
</div>
I only applied some styling ti increase visibility of the changes.
.img {
width: 32%;
height: 100px;
background-color: #ccc;
display: inline-block;
}
.row {
border: 1px solid green
}
.big-img {
height: 300px;
}
And finally the JS:
$('.img').click(function() {
var expandedImg = '<div class="big-img"></div>';
$('.big-img').remove();
$(this).parent().append(expandedImg);
})
Fiddle: https://jsfiddle.net/a5fm2dup/
why don't you just do
$(".Wrapper").on("click", ".testDivs", function () {
$(this).after($(".fullWidthDiv"));
});
Ended up making a solution based on my initial code. This doesn't require all the CSS the other solution that was postet suggested. Adding rows dynamically was also suggested, but this became very complicated when making it responsive to window resizing. Feel free to reply if you have any comments on this
function positionDiv() {
var checker = false;
var n;
var thisTop = clickedElement.position().top;
$(".testDivs").each(function(i, obj) {
var otherTop = $(obj).position().top;
if(thisTop < otherTop){
$(".testDivs:eq(" + (i-1) + ")").after($(".fullWidthDiv"));
checker = true;
return false;
}
n = i;
});
if (!checker) {
$(".testDivs:eq(" + n + ")").after($(".fullWidthDiv"));
}
}
var clickChecker = null;
$(".wrapper").on("click", ".testDivs", function () {
if (clickChecker === this){
$(".fullWidthDiv").hide();
clickChecker = null;
} else {
$(".fullWidthDiv").show();
clickChecker = this;
}
clickedElement = $(this);
positionDiv();
});
window.onresize = function(event) {
if( clickedElement != null) {
$(".tagTextWrapper").hide();
positionDiv();
$(".tagTextWrapper").show();
}
}

Categories