How to move a div after another using animations - javascript

I'm currently moving a div from one location to another, but I want to do it with some animations. Just have it slide to place and push the other divs down. How would I go about doing this?
Here is what I have so far.
var row = $('<div class="row">Another row inserted</div>');
$('.container').append(row);
$('.button').click(function() {
$('.row').addClass('row-changed');
$('.container > div:nth-child(2)').after(row);
});
.row {
color: blue;
}
.row-changed {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>
<button class='button'>Move</button>
<div class='row'>Row here</div>
<div class='row'>Row here</div>
<div class='row'>Row here</div>
<div class='row'>Row here</div>
<div class='row'>Row here</div>
</div>

try this one
var row = $('<div class="row">Another row inserted</div>');
$('.container').append(row.hide().slideDown());
$('.button').click(function() {
$('.row').addClass('row-changed');
var clone = row.clone().css("position", "absolute");
$('.container').append(clone);
row.css("visibility", "hidden");
var sel = $('.container > div:nth-child(2)');
sel.after(row.hide().slideDown());
var position = sel.next().position();
clone.animate({
left: position.left,
top: position.top
}, 400, function() {
clone.remove();
row.css("visibility", "visible");
});
});
.row {
color: blue;
}
.row-changed {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>
<button class='button'>Move</button>
<div class='row'>Row here</div>
<div class='row'>Row here</div>
<div class='row'>Row here</div>
<div class='row'>Row here</div>
<div class='row'>Row here</div>
</div>

Related

jQuery click append elements to series of divs

I have the following code:
$('button').click(function(e) {
e.preventDefault();
var count = 0;
if (count < 5) {
$(".container .column:nth-child(1)").append('<div class="element"></div>');
count++;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button">Add</button>
<div class="container">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
When I click the button I want to add 4 elements maximum in each column, one by one. For example if I click the button 6 times, the HTML will look like this:
<div class="container">
<div class="column">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
<div class="column">
<div class="element"></div>
<div class="element"></div>
</div>
<div class="column"></div>
<div class="column"></div>
</div>
This adds 1 element div to the first column, each time I click a button, with a 4 element div limit.
How can I do the same for the next columns?
Bonus Question
Is it possible to also do the opposite when clicking a button to remove elements?
You can target the column div by checking the no of elements in it using the length property.
Additionally, You don't need :nth-child(1) property.
$('.add').click(function(e) {
e.preventDefault();
var count = 0;
if (count < 5) {
$(".container .column").filter(function() {
return $(this).children('.element').length < 4;
}).first()
.append('<div class="element">e</div>');
count++;
}
});
$('.remove').click(function(e) {
e.preventDefault();
$(".container .column .element:last").remove();
});
.column {
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" class="add">Add</button>
<button type="button" class="remove">Remove</button>
<div class="container">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
References:
.filter()
.first()
You can try this code:
$('button').click(function(e) {
e.preventDefault();
var columns = $(".container .column");
var added = false;
for (var i = 0; i < columns.length; i++) {
if (columns[i].childNodes.length < 4) {
$(columns[i]).append('<div class="element"></div>');
added = true;
break;
}
}
if (!added) {
console.log('All columns were filled!');
}
});
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.column {
flex: 1;
}
.element {
width: 10px;
height: 10px;
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button">Add</button>
<div class="container">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>

jQuery - progressivly showing div

I would like to show some divs, one by one, with a sliding effect from the left or right part of the screen. So far i'm stuck between this
<button id='animer'>animer</button>
<div class="left">from left</div>
<div class="right">from right</div>
<div class="left">from left</div>
<div class="right">from right</div>
<script>
$(function() {
$('.left, .right').hide();
$('#animer').click(function() {
$(".left").toggle("slide", {direction: "left"}, 500);
$(".right").toggle("slide", {direction: "right"}, 500);
});
});
</script>
and that
<button id='animer'>animer</button>
<div class="all">from left</div>
<div class="all">from right</div>
<div class="all">from left</div>
<div class="all">from right</div>
<script>
$(function() {
$('.all').hide();
$('#animer').click(function() {
$('.all').first().show('slow', function showNextOne() {
$(this).next('.all').show('slow', showNextOne);
});
});
});
</script>
But i need this to work no matter the divs order, because the "left" or "right" items will come randomly.
Help will be much appreciated as i am not as competent as i wished in jQuery. ^^
The following uses the all variable to keep a list of all of the divs. When the button is clicked, the slideNext() function is executed, checking the class of the current item to decide on toggle direction, and specifying slideNext (itself) as the function to run when the toggle is complete.
$(function() {
var all = $('.left, .right').hide();
$('#animer').click(function() {
var i = 0;
(function slideNext() {
if (i < all.length) {
var current = all.eq(i);
current.toggle("slide", {
direction: current.hasClass("left") ? "left" : "right"
}, 500, slideNext);
}
i++;
})();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script>
<button id='animer'>animer</button>
<div class="left">from left</div>
<div class="right">from right</div>
<div class="left">from left</div>
<div class="right">from right</div>
You can use index from each() loop for delay and set direction based on condition if current div hasClass() left or not.
$(function() {
$('div').hide();
$('#animer').click(function() {
$('div').each(function(i) {
let dir = $(this).hasClass('left') ? 'left' : 'right';
$(this).delay(i * 1000).toggle('slide', {direction: dir})
})
});
});
h1 {
font-family: Helvetica, Arial;
font-weight: bold;
font-size: 18px;
}
body {
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<h1>HTML Slider Test</h1>
<button id='animer'>animer</button>
<div class="left">from left</div>
<div class="right">from right</div>
<div class="left">from left</div>
<div class="right">from right</div>

Adding and removing classes depending on other elements

So I have carousel with slides (works on fullPage.js):
<div id="myContainer">
<div class="section" data-anchor="skynet">
<div class="slide one" data-anchor="main">
Slide 1
</div>
<div class="slide two" data-anchor="about_us">
Slide 2
</div>
<div class="slide three" data-anchor="faq">
Slide 3
</div>
<div class="slide four" data-anchor="news">
Slide 4
</div>
</div>
</div>
And I have some blocks with backgrounds
<div class="bg-main" id="bgOne"></div>
<div class="bg-main" id="bgTwo"></div>
<div class="bg-main" id="bgThree"></div>
<div class="bg-main" id="bgFour"></div>
Slides swaps by adding class active to blocks with class .one, .two etc.
I try to add class to blocks with background depend on active slide. For example - if .slide.two has class .active, add class to block #bgTwo.
Here my current JS. It doesn't work:
<script type="text/javascript">
$(document).ready(function(){
if ( $('#myContainer .one').hasClass('active') ) {
$('.bg-main').removeClass('active');
$('#bgOne').addClass('active');
} else if ( $('#myContainer .two').hasClass('active') )
{
$('.bg-main').removeClass('active');
$('#bgTwo').addClass('active');
}
});
</script>
Use the callback onSlideLeave
Demo
$(document).ready(function() {
$('#fullPage').fullpage({
onSlideLeave: function(link, secIdx, sldIdx, dir, next) {
$('.test .bg-main').removeClass('active');
$('.test .bg-main').eq(next).addClass('active');
}
});
});
.slide {
text-align: center
}
.test {
position: fixed;
top: 75%;
right:calc(50% - 220px);
}
.bg-main {
height: 30px;
width: 100px;
background: grey;
display:inline-block;
text-align:center;
outline:1px solid #fff;
margin:0;
}
.one,
#bgOne.active {
background: #fc0;
}
.two,
#bgTwo.active {
background: #f00;
}
.three,
#bgThree.active {
background: #0f0;
}
.four,
#bgFour.active {
background: #00f;
}
<link href='https://cdn.jsdelivr.net/jquery.fullpage/2.9.4/jquery.fullpage.min.css' rel='stylesheet'>
<div id="fullPage">
<div class="section" data-anchor="skynet">
<div class="slide one" data-anchor="main">
Slide 1
</div>
<div class="slide two" data-anchor="about_us">
Slide 2
</div>
<div class="slide three" data-anchor="faq">
Slide 3
</div>
<div class="slide four" data-anchor="news">
Slide 4
</div>
</div>
</div>
<div class='test'>
<div class="bg-main active" id="bgOne">1</div>
<div class="bg-main" id="bgTwo">2</div>
<div class="bg-main" id="bgThree">3</div>
<div class="bg-main" id="bgFour">4</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://cdn.jsdelivr.net/jquery.fullpage/2.9.4/jquery.fullpage.min.js'></script>
So i found out that fullpage.js use event afterSlideLoad. So thats my solution:
<script type="text/javascript">
$(document).ready(function() {
$('#myContainer').fullpage({
anchors: ['skynet'],
menu: '#menu',
scrollingSpeed: 500,
normalScrollElements: '.modal',
scrollOverflow: true,
afterSlideLoad: function( anchorLink, index, slideAnchor, slideIndex){
var loadedSlide = $(this);
if(slideIndex == 0){
$('.bg-main').removeClass('active');
$('#bgOne').addClass('active');}
if(slideIndex == 1){
$('.bg-main').removeClass('active');
$('#bgTwo').addClass('active');}
if(slideIndex == 2){
$('.bg-main').removeClass('active');
$('#bgThree').addClass('active');}
if(slideIndex == 3){
$('.bg-main').removeClass('active');
$('#bgFour').addClass('active');}
}
})
});
</script>
Class is added only after the slide is changed, and not during the process itself. The background does not change as fast as I'd like, but this is the best thing I could achieve.
The perfect solution is to extend the fullpage.js to handle the feature.
This is a workaround:
<script type="text/javascript">
var updateClasses = function(){
var activeClass = 'active';
var eq = $('#myContainer').children(activeClass).eq();
var bgMain = $('.bg-main').removeClass(activeClass);
bgMain.eq(eq).addClass(activeClass);
};
$(document).ready(function(){
$(".fp-controlArrow").on("click.updateClasses", function(){
updateClasses();
});
});
</script>

Refactoring jQuery repeating pattern

I have painted my self into a corner in order to quickly prototype.
What's the best way to refactor the following jQuery code? Its functionality is to toggle between some sidebar navigation items. I need it to be more dynamic in order to be scalable.
Would you add the IDs inside the if statements, in an array and iterate through them? Use variables? Create a function and call it on the html side onClick? No matter what I think of, it stills leads to a bunch of repeating code.
Thank you!
// TOGGLING LEFT NAVIGATION
$('#settingsClick').click(function() {
if( $('#addContainer, #noteContainer, #logoContainer, #themeContainer').is(':visible') ) {
$('#addContainer').slideUp(350);
$('#noteContainer').slideUp(350);
$('#logoContainer').slideUp(350);
$('#settingsContainer').slideDown(350);
$('#themeContainer').slideUp(350);
} else {
$('#settingsContainer').slideToggle(350);
}
});
$('#addClick').click(function() {
if( $('#settingsContainer, #noteContainer, #logoContainer, #themeContainer').is(':visible') ) {
$('#settingsContainer').slideUp(350);
$('#noteContainer').slideUp(350);
$('#logoContainer').slideUp(350);
$('#addContainer').slideDown(350);
$('#themeContainer').slideUp(350);
} else {
$('#addContainer').slideToggle(350);
}
});
$('#noteClick').click(function() {
if( $('#settingsContainer, #addContainer, #logoContainer, #themeContainer').is(':visible') ) {
$('#settingsContainer').slideUp(350);
$('#addContainer').slideUp(350);
$('#logoContainer').slideUp(350);
$('#noteContainer').slideDown(350);
$('#themeContainer').slideUp(350);
} else {
$('#noteContainer').slideToggle(350);
}
});
$('#logoClick').click(function() {
if( $('#settingsContainer, #addContainer, #noteContainer, #themeContainer').is(':visible') ) {
$('#settingsContainer').slideUp(350);
$('#addContainer').slideUp(350);
$('#noteContainer').slideUp(350);
$('#logoContainer').slideDown(350);
$('#themeContainer').slideUp(350);
} else {
$('#logoContainer').slideToggle(350);
}
});
$('#themeClick').click(function() {
if( $('#settingsContainer, #addContainer, #noteContainer, #logoContainer').is(':visible') ) {
$('#settingsContainer').slideUp(350);
$('#addContainer').slideUp(350);
$('#noteContainer').slideUp(350);
$('#logoContainer').slideUp(350);
$('#themeContainer').slideDown(350);
} else {
$('#themeContainer').slideToggle(350);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="settingsClick">Click Me</a><br>
<div id="settingsContainer">Content...</div>
<br><br>
<a id="addClick">Click Me</a><br>
<div id="addContainer">Content...</div>
<br><br>
<p> Etc... Etc....</p>
You should group using the common CSS class, i.e. header and content. Using the established relationship you can target the others content holder and content associated with the current clicked header element.
$('.container .header').on('click', function() {
//Get the current element
var $this = $(this);
//find the content
var $content = $this.closest('.container').find('.content'); //$this.next()
//get all contents
var content = $('.container .content');
//Slide up others
content.not($content).slideUp(350);
//Slide down
$content.slideToggle(350);
});
.content {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="header" id="settingsClick">Click Me</div>
<div class="content" id="settingsContainer">Content...</div>
</div>
<div class="container">
<div class="header" id="addClick">Click Me</div>
<div class="content" id="addContainer">Content...</div>
</div>
<div class="container">
<div class="header" id="noteClick">Click Me</div>
<div class="content" id="noteContainer">Content...</div>
</div>
the best bet would be to do it like so
$(document).on('click', ".trigger", function() {
var sibling_content = $(this).siblings(".content");
if (!sibling_content.hasClass('active')) {
$(".content").slideUp('slow').removeClass('active');
sibling_content.slideDown('slow').addClass('active');
} else {
sibling_content.slideUp('slow').removeClass('active');
}
})
.trigger {
background-color: red;
color: white;
font-size: 16px;
}
.content {
background-color: blue;
color: white;
font-size: 16px;
padding: 20px 0;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="trigger">trigger</div>
<div class="content">content</div>
</div>
<div class="container">
<div class="trigger">trigger</div>
<div class="content">content</div>
</div>
<div class="container">
<div class="trigger">trigger</div>
<div class="content">content</div>
</div>
<div class="container">
<div class="trigger">trigger</div>
<div class="content">content</div>
</div>

how to check if it was the last element

how can I check if it was the last div? If it was I need to remove all classes "ready"
html:
<div class="green"></div>
<div class="orange"></div>
<div class="red"></div>
<div class="green"></div>
<div class="orange"></div>
js:
$(function() {
setInterval(showBlock, 1000);
function showBlock() {
var x = $("div:first").addClass("ready");
var c = $("div");
$(".ready").css("display", "block");
if (c.hasClass("ready")) {
$(".ready:last").next().addClass("ready");
}
}
})
;
Looking at your code what I understand is you want display one div after each second. For that I'll suggest following approach.
First add hidden class to all divs and then remove it from first hidden div at each second.
$(function() {
$('div').addClass('hidden');
var i = setInterval(showBlock, 1000);
function showBlock() {
var x = $("div.hidden:first").removeClass("hidden");
if($("div.hidden").length == 0) {
clearInterval(i);
}
}
});
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="green">Green</div>
<div class="orange">Orange</div>
<div class="red">Red</div>
<div class="green">Green</div>
<div class="orange">Orange</div>
As far as I understand your problem, following solution must work in your case:
$(function() {
setInterval(showBlock, 1000);
function showBlock() {
var ready_divs = $("div.ready").length;
var total_divs = $("div").length;
if(ready_divs!=total_divs){
if(ready_divs==0){
$("div:first").addClass('ready');
}else{
$("div.ready:last").next('div').addClass('ready');
}
}else{
$("div").removeClass('ready')
}
}
});
div{
width: 20px;
height: 20px;
border:1px solid red;
}
div.ready{
border:3px solid blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="green"></div>
<div class="orange"></div>
<div class="red"></div>
<div class="green"></div>
<div class="orange"></div>

Categories

Resources