Apply class to divs within HTML being AJAX called? - javascript

I am appending new HTML on a load more button, like this:
function addStuff() {
$.get('page-partials/more-stuff.html', function(stuff) {
$('#load-button').append(stuff);
});
};
The trouble is that this new content is being put into a container (with a dynamic height), which I want to animate down when more things are added. For this reason, I need to add a dynamic class to divs inside 'more-stuff.html', each time that template is added again.
Eg:
<div class='stuff added1'></div>
And then the next time it's added:
<div class='stuff added2'></div>
Etc. Is this possible? Otherwise, does anyone know of a solution to animate height changes from an undetermined non-zero number to another undetermined non-zero number?

What about
var count = 0;
$.get('page-partials/more-stuff.html', function(stuff) {
count++;
$('#load-button').append(stuff).addClass('stuff added'+count);
});

Actually vivek mentioned a better approach but that has to be something like this:
var stuff = '<div style="height:200px;">Dynamically appended div</div>'; // ajax response
var h = $(stuff).height();// find out the height of it.
$('.stuff').append(stuff).css('height', h); // after append just update the height.
.stuff {
height:60px;
width:100px;
border:2px solid #f00;
-webkit-transition: height 0.8s ease-in-out;
-moz-transition: height 0.8s ease-in-out;
-o-transition: height 0.8s ease-in-out;
transition: height 0.8s ease-in-out; /* <------css3 transition to animate the height */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='stuff'></div>

Try chaining added function to each call to addStuff
function addStuff() {
// `return` jQuery promise object from `addStuff`
return $.get('page-partials/more-stuff.html', function(stuff) {
$('#load-button').append(stuff);
});
};
var added = function() {
$(".stuff").each(function(index) {
$(this).addClass("added" + index + 1)
})
}
addStuff().then(added);

Related

Transition Opacity w/javascript not working

I want to fadein a component after ajax call completes and jquery has rebuilt DOM.
I have this setup:
index.html:
<head>
<style>
body {
opacity: 0;
transition: opacity 2s;
}
</style>
</head>
<body onload="document.body.style.opacity='1'">
<div class="content">
<!-- Markup for content -->
</div>
</body>
main.css
.content {
opacity: 0;
transition: opacity 6s;
transition: opacity 2s;
-webkit-transition: opacity 6s;
-moz-transition: opacity 6s;
}
main.js
$(document).ready(function () {
const contentEl = document.querySelector(".content");
$(".submit").on("click", async function (e) {
e.preventDefault();
console.log(contentEl.style.opacity);
if (contentEl.style.opacity == 1) {
contentEl.style.opacity = 0;
console.log("Style opacity is in if and = %s", contentEl.style.opacity);
}
// Do Ajax and update DOM via jQuery
contentEl.style.opacity = 1;
}
The first time thru .content fades in as expected as well as fade in of whole page on initial render. However subsequent times thru there is no transition effect. Logging shows that I am changing style.opacity from 1 -> 0 and back to 1 after initial iteration. Any CSS guru's versed in CSS's dark secrets input advice appreciated.
$(document).ready(function () {
const contentEl = document.querySelector(".content");
contentEl.style.opacity = 1; // Define initial opacity (starting val)
$(".submit").on("click", async function (e) {
e.preventDefault();
contentEl.style.opacity = 0; // on click set opacity to 0?
FadeIn(); // Let's Fade from 0 to 1!
});
let FadeIn = () => { // Function
if (contentEl.style.opacity < 1) { // If opacity doesn't equal 1
contentEl.style.opacity += 0.2; // Let's add 0.2!
setTimeout(FadeIn(), 300); // Hell let's repeat that more 300ms
}
}; // Once we equal 1 we should be done
});
I don't play with the JQuery like that, I much rather too use CSS entirely for the animation process of these types of things, it's cleaner (less jitter). I'm assuming this is what you're sort of after though, a simple set value and slowly loop till finished. Button will start out 1 opacity, when clicked jump to 0 and slowly climb its way back up to 1.

How to stop one eventListener when start another on the same element?

I'm creating some kind of gallery in js as a practice. I found an error and I don't know how to solve it.
Full code of on JSFiddle ->
Code
Background
I add two eventListeners to my img wrapper,
wrapper looks like that:
<div class="gallery-item"> <-- wrapper
<img src=""> <-- image
<div> <-- overlay
</div>
</div>
and listeners like that (listeners I'm adding during creating wrappers in js):
imageWrapper.addEventListener('mouseenter', enableOverlay, false);
imageWrapper.addEventListener('mouseleave', disableOverlay, false);
Listeners invokes functions, which are responsible for displaying overlay over image. First of them show overlay with fade effect and the second one hide it with the same effect.
enableOverlay
function enableOverlay(e) {
var el = this.childNodes[1].style;
el.display = 'block';
(function fadeIn() {
if (el.opacity < 1) {
el.opacity = parseFloat(el.opacity) + Number(0.1);
setTimeout(fadeIn, 30);
}
}());
}
disableOverlay
function disableOverlay(e) {
var el = this.childNodes[1].style;
(function fadeOut() {
if (el.opacity > 0) {
el.opacity = parseFloat(el.opacity) - Number(0.1);
setTimeout(fadeOut, 30);
} else {
el.display = 'none';
}
}());
}
Problem
On first sight everything is ok if I'm slowly move mouse over images - one function ends (opacity = 1) and the second is starting until opacity = 0. But when I'm moving mouse fast over images, overlays start to blink - opacity increases and decreases by 0.1 (value in IIFEs) and script loop.
As I figured out, reason of this behavior is that enableOverlay dosen't finish (el.opacity dosen't reach 1) and in the same time disableOverlay starts. And I don't know how to fix this situation.
I was trying to deal with it using flags which represents the state of fading function and breaks IFFEs, but it didn't help.
Long story short, can anyone help me with this problem or show me a way of thinking to solve it?
EDIT
In my opinion, my problem is 'how to stop function in one eventListener when another eventListeners is fired'. Changing opacity is only a sample.
You can use css transition.
function enableOverlay(e) {
var el = this.childNodes[1].style;
el.opacity = '1';
}
function disableOverlay(e) {
var el = this.childNodes[1].style;
el.opacity = '0';
}
.gallery-item img+div {
cursor: pointer;
opacity: 0;
-webkit-transition: opacity .3s ease;
-moz-transition: opacity .3s ease;
-o-transition: opacity .3s ease;
-ms-transition: opacity .3s ease;
transition: opacity .3s ease;
}
https://jsfiddle.net/zjqpxzmj/
Just added an attribute to track the event.
Fiddle
function disableOverlay(e) {
var el = this.childNodes[1].style;
var that = this.childNodes[1];
that.setAttribute('op','fadeOut');
(function fadeOut() {
if (el.opacity > 0 && that.getAttribute('op')==='fadeOut') {
el.opacity = parseFloat(el.opacity) - Number(0.1);
setTimeout(fadeOut, 30);
} else {
el.display = 'none';
}
}());
}
In your case, catching the latest setTimeout and calling clearTimeout on it from the other function should help.

Jquery - Reverse animation on click (toggle or if/else)

I've tried a lot of different options and I'm sure most would work if I knew what I was doing.
I want to click on an image and make it larger and centered in the screen, then I want to click on the same image and return it back to normal.
In the two individual scripts below I have erased the reverse effect but I basically used functions that changed the css settings back to width:250, height:250, and marginLeft:9%. All I could get it to do successfully was enlarge an image but then it shrank automatically once it had fully enlarged. I need to make the function enlarge and then wait until I click the image again for it to shrink.
<script>
$('document').ready(function(){
$('.hello_mom').on('click', function(){
$('.lbs_lease').animate({
width:"350px",
height:"350px",
zIndex:"10",
marginLeft:"28.4%"
}, 500 );
});
});
</script>
<!--<script>//My idea with this second script was to set an initial variable that I would use to make the enlargement animation run (with an if statement) and the shrinking animation stop until the variable was changed at the end of the function. Once the variable changes the else statement would become true and run my reverse animation. However, it seems redundant when the animation still doesn't wait for another click to occur before it runs.
$a = 5;
$c = 10;
var b = $a;
if(b < $c) {
$('.lbs_lease').animate({
width:"350px",
height:"350px",
zIndex:"10",
marginLeft:"28.4%"
}, 500 )};
</script>-->
you have 2 ways to do that ..
1- by using addClass and removeClass with transition
in css
.imageClicked{
width:350px;
height:350px;
zIndex:10;
marginLeft:28.4%;
transition : 0.5;
}
js
$('document').ready(function(){
$('.hello_mom').on('click', function(){
if($('.lbs_lease').hasClass('imageClicked')){
$('.lbs_lease').removeClass('imageClicked');
}else{
$('.lbs_lease').addClass('imageClicked');
}
});
});
2- by make another animate with default style and use boolean true or false
$('document').ready(function(){
var imgClicked = true;
$('.hello_mom').on('click', function(){
if(imgClicked == true){
$('.lbs_lease').animate({
width:"350px",
height:"350px",
zIndex:"10",
marginLeft:"28.4%"
}, 500 );
imgClicked = false;
}else{
$('.lbs_lease').animate({
//type your default style here
}, 500 );
imgClicked = true;
}
});
});
something like this:
var left = true;
$('.hello_mom').on('click', function () {
if (left) {
$(this).animate({
'marginLeft': "-=30px"
});
left = false;
} else {
$(this).animate({
'marginLeft': "+=30px"
});
left = true;
}
});
http://jsfiddle.net/e1cy8nLm/
You can do something like this: JSFiddle Demo
$('img').on('click', function(){
$(this).toggleClass( 'enlarge' );
});
CSS:
img {
// set the initial height and width here so we can animate these properties.
width:100px;
height:100px;
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
// toggle this class with jQuery to enlarge the img on click
.enlarge {
width:200px;
height:200px;
}
One of the methods will be using addClass and removeClass jquery functions keeping track of the current state of image.
The enlarged variable has the current state of the image and toggles it onclick with addition or removal of class.
Note the transition time is mentioned for both the classes, the added/removed as well as the original styling class to prevent abrupt transition while resizing to both states.
Here is a jsfiddle for that : JS FIDDLE DEMO
HTML Code :
<div>
<img class="hello_mom" src="http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg" />
</div>
CSS Code :
.hello_mom{
width:250px;
height:250px;
background : red;
-webkit-transition: all 0.5s; /* Safari */
transition: all 0.5s;
}
.hov_class{
width:350px;
height:350px;
z-index:10;
//margin-left:28.4%;
-webkit-transition: all 0.5s; /* Safari */
transition: all 0.5s;
}
JS Code :
var enlarged=0;
$('document').ready(function(){
$('.hello_mom').on('click', function(){
if(!enlarged){
$('.hello_mom').addClass("hov_class");
enlarged=1;
}
else{
$('.hello_mom').removeClass("hov_class");
enlarged=0;
}
});
});
Take a look at this
http://julian.com/research/velocity/
Velocity is javascript animation, made faster than CSS animation.
...and here you also have a reverse method

Fading in and out text in block

I have a block which content is being dynamically changed by script and I want that content not to change instantly, but fade out and then fade in with new content.
I want that done without jQuery — pure JS and CSS.
I am trying to do this in such a way:
I've defined transparent and opacle classes in CSS with transition set to 2s, and wanna toggle that classes for block with content when the content changes. As I expect it should smoothly fade out old content and fade in new content. But in fact content just changes instantly.
CSS:
.non-opacle {
opacity:0;
transition: opacity 2s linear;
}
.opacle {
opacity:1;
transition: opacity 2s linear;
}
HTML
<div class="alert alert-info" id="wrapper">
<p id="text-box">…</p>
</div>
JS
var textBox = document.getElementById('text-box');
window.onload = function () {
var failCounter = 0;
var current = notes[Math.floor(Math.random() * 12)];
textBox.className = 'opacle';
textBox.innerHTML = '…';
function keyClicked(event) {
if (event.target.className.split(' ')[1] === current) {
textBox.className = 'non-opacle';
textBox.innerHTML = '*some altered content*';
textBox.className = 'opacle';
…
In JS I initially set content wrapper block to 'opacle' class with initial content, and then on certain conditions, I set it to 'non-opacle', change block's innerHTML to place relevant content, and set the class back to 'opacle'.
But no animation occurs( What am I doing wrong?
Your problem is that you're adding and removing the opacity at the same time, before the initial transition has had time to complete.
What you need to do is delay the changing of the innerHTML and resetting of the opacity until the transition has completed.
Here's a very simple looping example to illustrate the principle, the important part to note is the setTimeout.
var p=document.getElementById("change"),text=["One","Two","Three","Four","Five"],x=0,interval=setInterval(function(){
x++;if(x===text.length)x=0;
p.classList.add("hide");
setTimeout(function(){
p.innerHTML=text[x];
p.classList.remove("hide");
},500);
},2000);
#change{
color:#000;
font-family:arial;
padding:5px;
transition:opacity .5s linear;
}
.hide{
opacity:0;
}
<p id="change">One</p>
The browser is not going to wait for transitions to complete before setting the class back to opacle.
This simple working fiddle moves the transition out to a separate selector, and uses a transitionend event listener, to wait for the element to be completely faded out before changing the content and fading it back in.
http://jsfiddle.net/0m3Lpwxo/1/
CSS:
.opacle {
opacity:1;
}
.non-opacle {
opacity:0;
}
#test {
transition: opacity 1s linear;
}
html:
<div id="test" class="non-opacle">this is content</div>
<button onclick="toggle()">toggle</button>
js:
function transitionEnded() {
var el = document.getElementById('test');
el.innerHTML = "hello.";
el.classList.remove('non-opacle');
}
function toggle() {
var el = document.getElementById('test');
el.addEventListener("transitionend", transitionEnded, true);
el.classList.add('non-opacle');
}
You probably just need to define browser specific styles along side your current definition (for example: -webkit-transition: opacity 2s linear;)
Also, I would say that instead of adding the transition redundantly to both classes, target something about your element that's not going to change, like its ID and define the transition style rules there. That way you will keep your CSS more DRY.
Here's the best reference material for dealing with CSS transitions: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Try this:
<div id="myElement">Text</div>
function fadeOut(id,val){
if(isNaN(val)){ val = 9;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val>0){
val--;
setTimeout('fadeOut("'+id+'",'+val+')',90);
}else{return;}
}
function fadeIn(id,val){
if(isNaN(val)){ val = 0;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val<9){
val++;
setTimeout('fadeIn("'+id+'",'+val+')',90);
}else{return;}
}
Referred from this.
I have used following JS:
function change(){
var d = document.getElementById("div");
d.className = d.className + " non-opacle";
setTimeout(function(){
d.className = "opacle";
d.innerHTML = "TEST";
},1000);
}
See following DEMO, with CSS:
.opacle {
opacity:1;
transition: opacity 1s linear;
}
.non-opacle {
opacity:0;/* No need to add transaction here */
}

Jquery Fadein/FadeOut simultaneously

How are you?
This is from a previous post and a solution was posted.
JS :
$(document).ready(function() {
var allBoxes = $("div.boxes").children("div");
transitionBox(null, allBoxes.first());
});
function transitionBox(from, to) {
function next() {
var nextTo;
if (to.is(":last-child")) {
nextTo = to.closest(".boxes").children("div").first();
} else {
nextTo = to.next();
}
to.fadeIn(500, function() {
setTimeout(function() {
transitionBox(to, nextTo);
}, 5000);
});
}
if (from) {
from.fadeOut(500, next);
} else {
next();
}
}
JSFIDDLE HERE
However I was trying to extend this a bit, where when box 1 fades out, you can see box 2 fading in slightly at the same time - simultaneously, and as box2 fades out ...box 3 is fading in at the same time with the opacity going from 0 to 1
I'm fine and you? :') .
I have a solution that maybe can help.
Have you tried making 1 class named display and setting display: block; and then put it on the function as toggleClass(). Finally you make a new class named as .transition(I do this with all my project to make them easier) and put it on the div or add it with some code like: $("div").addClass("transition");.
the code for .transition should be like this:
.transition {
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
You can also try insted of CSS and jQuery using only CSS.
an example could be using CSS Animations. Define the class of every box and then make a animation and add a delay on every animation so it will show every certain time, make them infinite so the will loop.
Hope you understand :)
Editing line 14 of your jsFiddle to add a delay created a smoother effect so you don't see two at once. Which I surmise is the answer to the question.
Line 14 edits: to.delay(100).fadeIn(500, function () {

Categories

Resources