Reputation: 109
I want to append .item
from .left
to .right
on page load and resize when $(window).width() < 479
. The problem is that with multiple instances, the resize function re-iterates to append .item
several times.
How do I change the code so that it only executes once per .item
?
codepen.io/moofawsaw/pen/PoNVejV
function moveDiv() {
if ($(window).width() < 479) {
$('.item').appendTo('.right');
} else {
$('.item').appendTo('.left');
}
}
moveDiv();
$(window).resize(moveDiv);
body {
display: flex;
}
.post {
display: flex
}
.item {
height: 100px;
width: 100px;
border: 2px solid;
}
.right,
.left {
min-width: 100px;
height: 200px;
}
.right {
background: silver;
}
.left {
background: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="post">
<div class="right">
<div class="item"></div>
</div>
<div class="left"></div>
</div>
<div class="post">
<div class="right">
<div class="item"></div>
</div>
<div class="left"></div>
</div>
Upvotes: 2
Views: 117
Reputation: 1057
If I would answer the given question, here it is.
The main problem in the given code was that $('.item')
selects all existing .item
s and clones them as much as there are .right
or .left
items on the page. It would work perfectly if you had only one of those .right
or .left
containers.
So to solve this one we won't select all .item
s at once and instead we would process each .item
separately using convenient jQuery function .each()
function moveDiv() {
if ($(window).width() < 479) {
moveItemInPostTo('.right');
} else {
moveItemInPostTo('.left');
}
}
function moveItemInPostTo(selector) {
// Instead of working with all .item elements at once,
// iterate over each one separately
$('.item').each(function(i, el) {
// Get parent container, in which we can find
// both .left and .right elements
var $post = $(el.closest('.post'));
// Move the .item to one of them
$(el).appendTo($post.find(selector));
})
}
moveDiv();
$(window).resize(moveDiv);
body {
display: flex;
}
.post {
display: flex
}
.item {
height: 100px;
width: 100px;
border: 2px solid;
}
.right,
.left {
min-width: 100px;
height: 200px;
}
.right {
background: silver;
}
.left {
background: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="post">
<div class="right">
<div class="item"></div>
</div>
<div class="left"></div>
</div>
<div class="post">
<div class="right">
<div class="item"></div>
</div>
<div class="left"></div>
</div>
Though this code works well, I would really recommend you solve this one in a non-javascript way (probably, just CSS). And if it still should be done using javascript - at least don't use jQuery. It is not really optimized in terms of how much it is pressuring the internet traffic (almost 90KB), and every thing you do with jQuery you can achieve using plain Javascript. Although, gotta admit, it's good for starters.
I answered your question, but if you would provide more details on what are your trying to achieve, I probably could give you another good answer.
Upvotes: 1