Assigning classes to a slide within a basic css slider - javascript

Basically I have a really simple (makes a change) slider that is done with css only. There are labels for the nav buttons and they are unique for each slide. Question is , How can I add/remove classes to certain items within the slide ONLY WHEN the slide is navigated to.
As with sliders they tend to load everything when the slider loads and I want to add cool animations to the bits on the slides so makes it pointless if everything loads at slide one.
jsfiddle http://jsfiddle.net/greggy_coding/013481b9/3/
I have provided some jsfiddle mock up of the slider and the classes animated and fade which are the ones in this instance i want to add and remove on the specific slide loading .. I will then assign them to different bits on the slide...
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
.fadeInUpBig {
-webkit-animation-name: fadeInUpBig;
animation-name: fadeInUpBig;
opacity: 0.3;
background-color: rgba(0,0,0,0.3);
}

CSS allows you to create animations with transitions and keyframes that once were only possible with JavaScript or Flash. Unfortunately, with CSS there’s no way to perform a callback when an animation is complete. With JavaScript, it’s possible to detect the end of a CSS transition or animation and then trigger a function.
Using JavaScript, we can detect the transitionend event; however for cross-browser, support we need to include the other browsers’ prefixes.
$(function() {
//Store a ref to slides
var $slides = $(".slides");
//Bind event to the contianed that gets animated
$(".slide-container")
.on("transitionend webkitTransitionEnd oTransitionEnd msTransitionEnd", function(e){
// Remove classes from all the elements within the active container that starts with the class 'add-anim'
$slides.find(".slide-container [class^='add-anim']").removeClass("animated bounceInLeft bounceInUp");
//Add appropriate classes to the matched elements within the active container
var $radio = $slides.find(":radio[name='radio-btn']:checked");
$radio.next(".slide-container").find(".add-anim-up").addClass("animated bounceInUp");
$radio.next(".slide-container").find(".add-anim-left").addClass("animated bounceInLeft");
});
});
Here is your entire code with HTML+JS+CSS.
Note: The above solution works, but the problem is, depending on the browser, it can fire twice (i.e. Chrome supports both webkitTransitionEnd and transitionend). There are ways to overcome this though, by detecting the supported event property. Take a look at this demo for more details.
Hope that helps.

Related

Tapping into fade events for Bootstrap 4

Many transitions in Bootstrap 4 provide a set of events to listen for. For example, you could do something like:
$('.certainDropdowns').on('hidden.bs.dropdown', function() {
// do the things
});
A light inspection of some of the components shows that somehow they are able to respond to fading. For example, the Bootstrap modal fires a "hidden" event once it has faded out. But this is at the modal level, not the transition level (hidden.bs.modal)
Unlike dropdowns and modals, there is not a "fade" JavaScript component. But the light scan of the source code seems to be indicating that Bootstrap provides emulation for CSS transitionEvent, and I'm trying to figure out how I can tap into it.
In brief:
Is there a Bootstrap 4-provided method for tapping into the fade transition's events, or am I limited to native transitionend (possibly with help from a 3rd-party polyfill)?
[edit to add content below]
I possibly should have tried transitionend before posting the question, but I just gave it a try and it seems to be no go like this:
<div id="something" class="fade show">Fadeable</div>
Then JS:
$('#something').on('transitionend', function() {
console.log('transition ended!');
});
//later
$('#something').removeClass('show');
This was tested only with the latest Firefox, which is one of my target browsers.
I couldn't find a way to do it in my intended way with the provided components. Instead, I ended up writing it as a single new class, "collapseFade" which could still use the Bootstrap pattern of adding/removing the class "show".
The tricky thing was that transitions would trample over each other if I just tried to add or remove the "show" class, so I had to add a second helper class, "out". This requires intimate understanding of the new classes, which was potentially hazardous to maintenance developers. Consequently, I wrote a jQuery plugin to go with it. Without using this answer as code repository, here's the lightweight breakdown:
SASS:
.collapseFade {
max-height: 400px;
transition:
max-height 0.5s,
opacity 0.5s 0.5s;
&:not(.show) {
opacity: 0;
max-height: 0;
}
}
.collapseFade.out {
transition:
max-height 0.5s 0.5s,
opacity 0.5s;
&:not(.show) {
opacity: 0;
max-height: 0;
}
}
(You could theoretically use Bootstrap's SASS fade variables instead of hard-coding time intervals).
Then the plug-in (code not included, for brevity) simply allows you to call collapseFade on an element. Eg. $('.something').collapseFade(). It optionally accepts "show" or "hide" as string parameters, but will just toggle by default. For whatever reason, transitionend is working here, so I also listen and fire an appropriate custom event for future maintenance or feature devs who might find it useful.
It functions thus: when showing, it removes the out class and adds the show class. When hiding, it adds the out class and then removes the show class.
The so-called "magic" is just in the timing. The second transition start is delayed by a value equal to the first transition time, which visually chains them together even though technically they are fired at the same time.
The other tricky bit is that the collapse animates max-height rather than height. This is the way Bootstrap themselves do it, and it makes sense... you can't animate "auto" height; it needs an actual target number. But straight-up "height" (no "max") means you're committed to occupying a certain amount of space. Max-height will allow height to be dynamic, but the trade-off is that it will operate smoothly only by restricting it as closely as possible. If I had put max-height of ten-thousand, for example, the collapsing animation wouldn't be smooth. You might notice that in Bootstrap's own collapse functionality, which is less than smooth for elements that are not tall. I don't anticipate my targets to be any taller than 400px so that's what I've provided.

FadeIn animation using CSS3 in Javascript

As jQuery.fadeIn is not very smooth on mobile devices I try to use CSS but it doesn't work as expected. How to create a smooth CSS animation using Javascript?
In general this is what I'm trying:
$('div')
.css('opacity', 0) // at first, set it transparent
.css('display', 'block') // make it appear
.css('transition', 'opacity 1000ms linear') // set a transition
.css('opacity', 1); // let it fade in
https://jsfiddle.net/8xa89y04/
EDIT1:
I'm not searching a solution using static CSS classes. The point is: I need to set this dynamically in Javascript code - a replacement for jQuerys fadeIn() for example.
Your logic isn't quite right. Firstly you cannot animate display, so to achieve what you require the element has to always be rendered in the DOM (ie. anything but display: none). Secondly, the transition property should be placed within the CSS styling itself. Finally you can make this much more simple by setting all the rules in CSS classes and just turning the class on/off. Try this:
div {
position: absolute;
width: 100px;
height: 100px;
background-color: black;
opacity: 0;
transition: opacity 1000ms linear;
}
.foo {
opacity: 1;
}
$('div').addClass('foo');
Working example
Use this code.
CSS
div {
width: 100px;
height: 100px;
background-color: black;
transition:opacity 2s;
}
JavaScript
$('div').hover(function(){
$(this).css('opacity','0');
})
Without using CSS properly, you are going the long way about it. You'll need to emulate what you would normally do in CSS, using JavaScript, so you'll be setting all your CSS properties, transitions etc, then applying them with js.
I can't personally see any benefit in doing this. Using actual CSS would be cleaner, more efficient, more maintainable, and simply a plain better solution to what you need.
I think this is what you are looking for.
$('div').css({"display":"block", "opacity":"0"}) //Make div visible and opacity as "0"
$('div').animate({opacity :1}, 1000); //Animate div to opacity "1"
Take a look at this Demo
Found the cause here: CSS transitions do not work when assigned trough JavaScript
To give this attention I need to give the browser some time - or better: a working slot to activate the transition as the time seems not to be a problem.
The following code cuts the process in two by using setTimeout()... and it works!
var div = $('div');
// first process
div
.css('opacity', 0) // initial opacity
.css('display', 'block') // make it appear (but still transparent)
.css('transition', 'opacity 1s linear'); // set up a transition for opacity
// break - start the transition in a new "thread" by using setTimeout()
window.setTimeout(function(){
div.css('opacity', 1); // start fade in
}, 1); // on my desktop browser only 1ms is enough but this
// may depend on the device performance
// maybe we need a bigger timeout on mobile devices

Angular JS and Animate.css: fade animation is janky

I have a dialog in which I'd like to display one of two things depending on the state of a variable. So, I hooked up 2 versions of a form with ng-if.
When you click "delete" button on first state, it toggles to the second state.
I wanted to make it less abrupt, so I tried adding some css:
[ng-if].ng-enter {
animation: fadeIn .5s;
}
[ng-if].ng-leave {
animation: fadeOut .5s;
}
These animations come from the bower package "animate css":
#keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}
.fadeIn {
animation-name: fadeIn;
}
However, as you can see in my animated GIF below, what happens is that for a second BOTH forms appear, making the dialog taller, then one fades out.
Is there no way to do a simple fadein/fadeout as in jQuery? I used to do this all the time with it, but trying to get nice UI animation in Angular is eluding me.
I had a similar problem with an Angular app and animations. I ended up having to use jquery - I wish I had a better answer - but it turned out beautifully. One note, though, I had to wrap any jquery I used in a noConflict() and use body on click plus the element because it doesn't exist yet in the DOM:
$.noConflict();jQuery( document ).ready(function( $ ) {
$('body').on('click', "#toggler", function(){
$('#div_to_show').slideDown();
});
});
I realize this a tangential answer and not an elegant solution but it worked for me to get it out the door under a tight deadline.
A clean solution is to change the state you use to check which form is to display when the animation ng-leave ends.
You can use a second variable to set the ng-leave class in the form that will be hidden.
I can't post you some code because i don't know your js and html.

Is it possible to make CSS transitions synchronous?

This code below demonstrates how I'm applying CSS transitions to the height property. My understanding of CSS transitions (which is supported by what I'm seeing) is that they are asynchronous. Can anyone tell me how to make CSS transitioning synchronous? I specifically want to use CSS transitions (i.e. not jQuery animations or some other method).
CSS:
.animated {
-webkit-transform-style: preserve-3d;
-webkit-transform: translate3d(0px,0px,0px);
transition: height 1.5s;
-webkit-transition: height 1.5s;
-webkit-perspective: 1500;
-webkit-backface-visibility: hidden;
}
HTML:
<div id='someElement' class='animated'></div>
JavaScript:
$("#someElement").css("height","200px");
//More javascript code I'd like to execute after the css animation has completed
Well, there isn't really a way to make it synchronous, but you can wait for the animation to end, effectively simulating a synchronous behaviour
The solution
var crossBrowserEvent = 'webkitAnimationEnd oanimationend msAnimationEnd animationend';
$("#someElement").css("height","200px");
$("#someElement").one('crossBrowserEvent',function(e) {
do_some();
magic();
here();
when_the_animation_ends();
});
Some additional comments
Because the css3 animations are not yet fully cross browser, you must listen to more then one event.
Some problems could arise if some of the browsers implement the new animationEnd event and also for example the webkitAnimationEnd at the same time. That's why I put the one event attacher instead of the on.
Here is a code that uses pure js and the webkit prefix to create sequential based class changes.
In the DEMO i use more than just one animation so the handler function is executed many times. Thats why i check for the propertyName('color' in my case). If the color animation ends the handler function changes the className with classList.toggle('active');
Each class has different transition lengths.
function handler(e){
//here is when the transition ends.
// add your code here or:
if(e.propertyName=='color'){
e.target.classList.toggle('active');
}
}
var div=document.getElementsByTagName('div')[0];
div.addEventListener('webkitTransitionEnd',handler,false);
div.classList.toggle('active');
DEMO (chrome safari android ios)
http://jsfiddle.net/jaqT7/
if you want more support search for the various prefixes.-webkit,-ms,-moz
and also the correct transitionend handler.
And here is an example using sequential animations using simple delay's
https://stackoverflow.com/a/20778358/2450730

Avoiding a CSS3 box-shadow to be seen while fading in a <li>

I'm fading in some <li> elements (boxes) when my users click a button. The boxes used to have PNG backgrounds and now I'm replacing them with pure CSS. I'm using Getting clever with CSS3 Shadows, using li:after.
The problem with this method is that when I fadeIn the boxes they'll naturally have opacity and thus the shadow will be seen through.
Setting the box-shadow on the <li> element doesn't create the shadow effect I'm after. I tried creating a that I append once the fadeIn is complete, and it sorta works but is noticeable.
Any ideas on a better way?
Could do with by wrapping it all up in a "wrapper" element inside the li element and then fading the li element.
Example: http://jsfiddle.net/petersendidit/ncBtV/1/embedded/result/
Only tested it in Chrome dev and Firefox 4
Can you add a class when the animation is completed...
CSS
li.completed-fade {
box-shadow: ...
}
jQuery
$('li').fadeIn(500, function() { $(this).addClass('completed-fade'); });

Categories