Animate Font Awesome Chevron icon rotation on collapse/expand - javascript

I want my icon to rotate visibly when the collapsible content is being hidden or is showing up.
Here's my function that adds a chevron icon and rotates it:
$('[data-toggle="collapse"]').each(function(){
var collapser = $(this);
// TODO: 'collapsed' class should be added manually if the toggled element is not shown
// i.e., if you remove 'show' class, add 'collapsed' class, or this function is confused
collapser.append('<span style="float:right;"><i class="fa fa-chevron-right'
+(collapser.hasClass('collapsed')?'':' fa-rotate-90')
+'"/></span>');
collapser.on('click', function(){
var chevron = collapser.find('.fa-chevron-right'); // it was replaced with svg
if (collapser.hasClass('collapsed')) {
chevron.addClass('fa-rotate-90');
} else {
chevron.removeClass('fa-rotate-90');
}
});
});
I'd like to add smoother transition, but better without css, by modifying this code only. CSS is tooo confusing for me
Any other critique of this code is welcomed

To make your animations smoother you can make use of the css transition property.
Simply add this code to your css:
.fa-chevron-right {
-webkit-transition: transform .4s; /* Safari */
transition: transform .4s;
}
or you can add the CSS directly with jQuery by modifying your code appending element this (not recommendet):
collapser.append('<span style="float:right;"><i style="transition: transform .4s;" class="fa fa-chevron-right'
+(collapser.hasClass('collapsed')?'':' fa-rotate-90')
+'"/></span>');
You can learn more about CSS transitions here:
https://www.w3schools.com/css/css3_transitions.asp
In general, I recommend you to learn CSS and create your animations whenever possible with it. You will see it's much easier and you get ways better performance.

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.

How to collapse left side panel?

I'm looking for a way to make this left side panel collapse. I not looking to have anything else on the map/site to move or adjust. Just to have the left panel collapsable. Ideally with a sliding animation rather than popping in and out.
Here's a link to my website with the panel in question
Would be immensely appreciated!
You can do this with a CSS transition on the left property to make changes to this value animate smoothly. Then add and remove a class that changes the left value to toggle the sidebar's visibility.
.left-side-bar {
transition: left .8s ease-in;
}
.left-side-bar.is-out {
left: -16.666%; /* equal to the sidebar's width */
}
It will be visible by default. Use JavaScript to add/remove the is-out class to make it hide.
The first thing you might want to do is use an api like Font Awesome to get some cool icons. You could add it with jQuery by the following cdn.
$('head').append('<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">');
Then create the div, css to hold the hamburger displayed using BS hidden-lg, hidden-md, hidden-sm. To hide it on anything larger than a phone. This would look like this.
<div class="mobile_bars hidden-lg hidden-md hidden-sm">
<button id="hide_menu">
<i class="fa fa-bars" aria-hidden="true"></i>
</button>
</div>
You can add this via jQuery, or simply add to your html.
Add the following CSS to your sites CSS to accommodate this element.
<style>
.mobile_bars {
margin-left: 262px;
margin-top: -32px;
}
/* NOTE* you don't need to write the CSS like this,
sense you'll add with jquery
.left-side-bar.is-out */
.push-in {
left: -16.666%; /* equal to the sidebar's width */
}
</style>
Then write your script using #keithjgrant code.
<script>
// Include Ready function
ALL is .TOUCH deprecated??
$('button#hide_menu').on( function(){
$('.left-side-bar').toggle('push-in animated fadeOutLeft');
// For some fun add animated.css to your header and add the following classes as well,
or visit https://daneden.github.io/animate.css/ to choose a class!
});
<script>
This wouldn't be my final result but it would get you close. Also I'm assuming your wanting this as a solution for a mobile website, however if your looking to use this a desktop option id simply change the icon, or add a left arrow icon to the right of the logo. Somewhere visible but out of the way!

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

Does jQuery animate between two different CSS classes?

I am trying to understand how jQuery animations work.
For instance, if I have an a element with CSS that makes it look like a clickable image and a given with and height in CSS, how would I safely animate the width and height of this element?
Do I need to animate the values in the CSS class? Or do I need to set a new CSS class with the target values for width and height, and let jQuery animate from oldClass to newClass?
Or can I simply use the .width() and .height() methods of jQuery, regardless of what values are specified in CSS?
What confuses me is: If I tweak the width of an element with jQuery, does this also modify my CSS, or does jQuery / JavaScript simply override the specified values in CSS with something else? I mean: After use jQuery to edit the width, does this width become the new value in the CSS file as well? Can I apply this class to other elements and they will have the new width?
It will overide inline style.
I will now show a version with top, left being animated but you can apply it on almost all CSS properties.
HTML
<span id="test">blablabla</span>
CSS
span{
position:absolute;
display:block;
height:50px;
width:50px;
}
jquery
$('#test').animate({top:'100px',left:'50px'}, 500);
fiddle
I know it's been a long time, but it may help someone looking for the answer anyway. Relying on CSS3 transition property can lead to trouble when wanting to support older browsers.
The requested behaviour of animating between two states (CSS Classes) can fully be accomplished by using jQuery UI, which supports this by extending the switchClass() method. It also supports all the perks of the animate() method, such as duration, easing, callback, etc.
As the official documentation states: '
Similar to native CSS transitions, jQuery UI's class animations
provide a smooth transition from one state to another while allowing
you to keep all the details about which styles to change in CSS and
out of your JavaScript.
You can read all about it here.
jQuery UI can also be compiled to include only the things you need, so you can reduce the size of the library by excluding the features you won't use. Check the available options here.
Hope it helped someone!
jQuery animate only animates numeric css values. It will not animate between classes (see example below for how to do that). The .animate() function adds the css you give it as a paramater and adds it as inline css. It will always override your stylesheet css. This is fine but a little messy and can get out of control very easily.
However, if you want to animate between classes, it is better for performance and cleaner to use css3 transition property. See example:
HTML
<div class="myTestAnimation">Something to test</div>
JQuery (could use vanilla javascript for this as well). Just toggling between classes. This way you don't have any styling info in your css at all.
jQuery(document).ready(function($) {
$(".myTestAnimation").click(function() {
$(this).toggleClass("animate");
});
});
CSS (this animates the width and height and background color) .animate() will not animate background color so that is an added bonus.
.myTestAnimation {
width: 50px;
height: 50px;
background-color: red;
-webkit-transition: background-color 300ms linear, width 300ms linear, height 300ms linear;
transition: background-color 300ms linear, width 300ms linear, height 300ms linear;
position: relative;
}
.myTestAnimation.animate {
background-color: blue;
width: 200px;
height: 200px;
}

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