I have an alert box that I want to use sessionStorage so that it only appears once. When the user clicks to close the alert, I want the box to disappear (display:none) but fade-out.
I read that you have to use two different functions - one that is activated when clicked and starts the transition and another the adds the 'display' style once transitioned. However, I can't get that to work:
<style>
.ddAlert {
padding: 20px;
box-sizing: border-box;
background-color: #f0ad4e;
color: #fff;
opacity: 1;
transition: opacity 1s;
}
.hide {
opacity: 0;
display: none;
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
let dismissed = sessionStorage.getItem("dismissed");
let alertDiv = document.getElementById("alert");
let dismissButton = document.getElementById("dismiss");
if (!dismissed) {
alertDiv.classList.remove("hide");
}
alertDiv.addEventListener("click", function() {
this.style.display = "block";
}.bind(alertDiv));
alertDiv.addEventListener("transitionend", function() {
if (this.className == "hide") {
this.style.display = "none";
}
sessionStorage.setItem("dismissed", true);
}.bind(alertDiv));
});
</script>
<div class="ddAlert hide" id="alert">
SOME ANNOYING ALERT HERE!
<button type="button" id="dismiss">X</button>
</div>
You are on the right track. Instead of listening on click on the alert, use the button as I assume it is there for that reason. When clicking the button the .hide class should be added to the alert. This will start the transition from opacity: 1; to opacity: 0;.
I suggest that instead of using inline-styles, that you stick to classes. Inline styles are hard to overwrite and prevents you from utilizing the full power of CSS. So I've added some classes in there to help you out.
Try out the example below.
<div class="ddAlert hidden" id="alert">
SOME ANNOYING ALERT HERE!
<button type="button" id="dismiss">X</button>
</div>
.ddAlert {
display: block;
transition: opacity 1s;
}
.hide {
opacity: 0;
}
.hidden {
display: none;
}
document.addEventListener("DOMContentLoaded", function() {
let dismissed = sessionStorage.getItem("dismissed");
let alertDiv = document.getElementById("alert");
let dismissButton = document.getElementById("dismiss");
if (!dismissed) {
alertDiv.classList.remove("hidden");
}
dismissButton.addEventListener("click", function() {
alertDiv.classList.add("hide");
});
alertDiv.addEventListener("transitionend", function({ target }) {
if (target.classList.contains("hide")) {
target.classList.add("hidden");
}
sessionStorage.setItem("dismissed", true);
});
});
This answer greatly lends from this SO question titled CSS3 Transition - Fade out effect which notes
When showing the element (by switching to the visible class), we want
the visibility:visible to kick in instantly, so it’s ok to transition
only the opacity property. And when hiding the element (by switching
to the hidden class), we want to delay the visibility:hidden
declaration, so that we can see the fade-out transition first. We’re
doing this by declaring a transition on the visibility property, with
a 0s duration and a delay.
I chose not to mark this question as a duplicate because it also involves the transitionend event. Additionally, I've focused only on the essence of the transition, with a minimal illustration.
The crucial element is the .dismissed-saved class.
let alertDiv = document.getElementById("alert");
let dismissButton = document.getElementById("dismiss");
dismissButton.addEventListener("click", function() {
// kick in the transition
alertDiv.classList.add("dismissed-saved");
// *this is where state should be committed
});
alertDiv.addEventListener("transitionend", function({
target
}) {
if (target === alertDiv) {
// clean up and show a nifty text message illustrating the event handler.
target.classList.add("hidden");
target.classList.remove("dismissed-saved");
document.getElementById("dismissed").classList.remove('hidden');
}
});
.ddAlert {
padding: 20px;
box-sizing: border-box;
background-color: #f0ad4e;
color: #fff;
opacity: 1;
}
.hidden {
display: none;
}
.dismissed-saved {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
<div class="ddAlert" id="alert">
SOME ANNOYING ALERT HERE!
<button type="button" id="dismiss">X</button>
</div>
<div id="dismissed" class="hidden">
Dismissed!
</div>
Good luck!
Related
I am sitting with a project in need of an overlay which fades out when hovered upon and goes to display: none (not visibility: hidden, it does need to be display: none).
The setup is a big confusing, but I will try to explain it:
The overlay comes up when I hover a menu point under my mega menu. When I move the cursor to the overlay it should naturally dissapear and the menu close.
This works very well with this code:
var element = document.getElementById("overlayed");
function mouseOver() {
element.classList.add("mystyle");
setTimeout(function() {
element.classList.remove("mystyle");
}, 500);
}
push {
position: absolute;
top: 50%;
}
.overlayerstwo {
position: fixed;
width: 100%;
top: 30%;
left: 0;
right: 0;
bottom: 0;
background: #111;
opacity: 0.5;
z-index: 2;
display: block;
visibility: visible;
}
.mystyle {
display: none;
animation-name: fadeOut;
animation-duration: .5s;
}
#keyframes fadeOut {
0% {
opacity: .5
}
100% {
opacity: 0;
}
}
.mystyler {
display: none;
}
<h1>Here is something. Overlay comes back when hovering me!</h1>
<div class="overlayerstwo" id="overlayed" onmouseover="mouseOver()"></div>
<div class="push">
<p>Here is an item being overlayed</p>
</div>
With this setup the overlay dissapears right away. I am trying to merge it with the fadeOut keyframe animation before it goes black. I have tried different tactics, like adding a second timeout event but all it does is loop through and end up showing the overlay permanently after.
So the order I want to achieve is as follows:
Add a class that fires the keyframe animation fadeOut for .5 sec
Remove keyframe animation class
Add display: block class
Remove display: block class (essentially resetting it, so you can get the overlay up again by hovering its triggerpoint)
So my question is, how do I get all of these to fire every time I hover over the overlay?
One of the things I tried was this:
var element = document.getElementById("overlayed");
element.classList.add("mystyle");
setTimeout(function(){
var element = document.getElementById("overlayed");
element.classList.remove("mystyle");
}, 500);
setTimeout(function(){
var element = document.getElementById("overlayed");
element.classList.add("mystyletwo");
}, 500);
setTimeout(function(){
var element = document.getElementById("overlayed");
element.classList.remove("mystyletwo");
}, 510);
With the css
.mystyle{
animation-name: fadeOut;
animation-duration: .5s;
}
.mystyletwo{
display: block;
}
Which did not work. I hope someone can help me figure out how to get it to work!
if the timeline will be like this: visible -> hover -> animation -> opacity to 0 -> display: none
using CSS with JS logic:
element.addEventListener("mouseover", function() {
element.style.opacity = "0";
element.style.transition = "all 0.3s";
// when finish the animation then call display none
setTimeout(function() {
element.style.display = "none";
}, 300); // put the same number (milliseconds) of duration of transition (or more, not less)
});
using this method you don't need to complex your code...
the trick really is because we use element.style
that is only put the CSS, but technically...
if there is a transition Javascript don't know it,
so it will run the setTimeout() directly after adding styles,
so now CSS will do the animation but javascript will quietly continue the code (which in our case, says that after 300 seconds add display: none;)
trying to make a button like this: https://gyazo.com/9afbd559c15bb707a2d1b24ac790cf7a. The problem with the code right now is that it works as it is supposed to on the first time; but after that, instead of going from left to right as intented, it goes from right to left to right.
HTML
<div class="btn-slide block relative mx-auto" style="overflow: hidden; width: 12rem;">
<span class="z-10">View Pricing</span>
<span class="slide-bg block absolute transition" style="background-color: rgba(0,0,0,.1); z-index: -1; top: 0; left:-10rem; width: 10rem; height: 3rem;"></span>
</div>
Javascript
const btns = document.querySelectorAll(".btn-slide");
const slide = document.getElementsByClassName('slide-bg');
btns.forEach(function(btn) {
btn.addEventListener('mouseout', function () {
slide[0].style.transform = 'translateX(230%)';
slide[0].style.transform = 'none';
})
btn.addEventListener('mouseover', function() {
slide[0].style.transform = 'translateX(80%)';
}, true)
})
Unless you have to compute a value in JavaScript (like the height of an element).
Use CSS classes as modifiers (is-hidden, is-folded, is-collapsed, ...).
Using JavaScript, only add/remove/toggle the class
yourElement.addEventListener(
"mouseenter",
function (event)
{
yourElement.classList.remove("is-collapsed");
}
);
yourElement.addEventListener(
"mouseleave",
function (event)
{
yourElement.classList.add("is-collapsed");
}
);
is-collapsed is only an exemple, name it according to your class naming standard.
You're probably going to need a bit more code than what you're showing, as you have two mutually exclusive CSS things you want to do: transition that background across the "button" on mouseenter/mouseout, which is animated, and then reset the background to its start position, which should absolutely not be animated. So you need to not just toggle the background, you also need to toggle whether or not to animation those changes.
function setupAnimation(container) {
const fg = container.querySelector('.label');
const bg = container.querySelector('.slide-bg');
const stop = evt => evt.stopPropagation();
// step one: make label text inert. This is critical.
fg.addEventListener('mouseenter', stop);
fg.addEventListener('mouseout', stop);
// mouse enter: start the slide in animation
container.addEventListener('mouseenter', evt => {
bg.classList.add('animate');
bg.classList.add('slide-in');
});
// mouse out: start the slide-out animation
container.addEventListener('mouseout', evt => {
bg.classList.remove('slide-in');
bg.classList.add('slide-out');
});
// when the slide-out transition is done,
// reset the CSS with animations _turned off_
bg.addEventListener('transitionend', evt => {
if (bg.classList.contains('slide-out')) {
bg.classList.remove('animate');
bg.classList.remove('slide-out');
}
});
}
setupAnimation(document.querySelector('.slide'));
.slide {
position: relative;
overflow: hidden;
width: 12rem;
height: 1.25rem;
cursor: pointer;
border: 1px solid black;
text-align: center;
}
.slide span {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.slide-bg {
background-color: rgba(0,0,0,.1);
transform: translate(-100%, 0);
transition: none;
z-index: 0;
}
.slide-bg.animate {
transition: transform 0.5s ease-in-out;
}
.slide-bg.slide-in {
transform: translate(0%, 0);
}
.slide-bg.slide-out {
transform: translate(100%, 0);
}
<div class="slide">
<span class="label">View Pricing</span>
<span class="slide-bg"></span>
</div>
And thanks to browsers being finicky with rapid succession mouseenter/mouseout events, depending on how fast you move the cursor this may not even be enough: you might very well still need a "step" tracker so that your JS knows which part of your total animation is currently active, and not trigger the mouseout code if, by the time the slide-in transition ends, the cursor is in fact (still) over the top container (or, again).
I advice you use the .on event listener
$('').on("mouseentre","elem",function(){$('').toggleclass('.classname')})
$('').on("mouseleave","elem",function(){$('').toggleclass('.classname')})
Then you can toggle css classes to your element in the function
toggle class adds the css of a class to your jquery selection, you can do it multiple times and have keyframes for animation in the css class
Keyframes are great way to implement animation and are supported on every browers
I have an element that works just fine with the following code. It's an object #obj1 that is hidden when loading the page, but appears when clicking on #obj2.
#obj1{
position:fixed;
width:100px;
bottom:180px;
right:100px;
display:none;
}
$("#obj1").hide();
$("#obj2").show();$('#obj2').toggle(function(){
$("#obj1").slideDown(function(){});
},function(){
$("#obj1").slideUp(function(){});
});
but I would like to have it like this:
$("#obj1").css({"opacity": "0","bottom": "180"})
$("#obj2").toggle(
function () {
$("#obj1").animate({"opacity": "1","bottom": "140"}, "slow");
},function () {
$("#obj1").animate({"opacity": "0","bottom": "180"}, "slow");
});
I would like it to fade in, but how do I add the animation to the first script? (animation ex: .animate({"opacity": "1","bottom": "140"}, "slow");)
Here is a super simple demo of fading in an element using CSS. You can use jQuery to add the class through a click event.
// HTML
<div id="myId" class="hide">
This is div with myId
</div>
// CSS
.hide {
display: none;
}
.myId {
animation: fadein 2s;
}
#keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
// JQUERY
$("#myId").removeClass("hide").addClass("myId");
You can see a working demo here. You'll just have to modify it to trigger on click of obj2 or where you like
EDIT - As per your comment above I have edited the pen, so now the element will be hidden on page load and then the class will be removed and the animation class added.
You would be best keeping the styles within css, and just using js to change the state (add/remove a class). The way you have the javascript is passable, but it'd be better for the class to be toggled based on itself so they can't accidentally get out of sync:
$('#obj2').on('click',function(e){
e.preventDefault();
if($('#obj1').hasClass('js-on'))
$('#obj1').removeClass('js-on');
else
$('#obj1').addClass('js-on');
});
#obj1{
position:absolute;
width:100px;
bottom:10px;
right:20px;
opacity: 0;
background-color: yellow;
padding: 1em;
transition: .5s opacity, .5s bottom;
}
#obj1.js-on {
opacity: 1;
bottom: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="obj2" href="#">Click me</a>
<div id="obj1">Hi</div>
$(document).ready(function() {
$("#obj1").hide();
$("#obj2").show();
});
$('#obj2').toggle(function(){
$("#obj1").slideToggle();
});
This will show obj1 by sliding when obj2 is pressed. To have it fade in instead Try,
$("#obj2").click(function () {
$("#obj1").fadeToggle("slow","swing");
This toggles obj1 fading in and out.
reference:
http://api.jquery.com/fadetoggle/
Slightly confused by the question, but here's my attempt at an answer: hope it helps
$(".obj1").click(function(){
$(".obj2").css('opacity', 0)
.slideDown('slow')
.animate(
{ opacity: 1 },
{ queue: false, duration: 'slow' }
);
});
.obj1 {
display: inline-block;
padding: 10px;
background: lightgrey;
}
.obj2 {
height: 100px;
width: 100px;
background: red;
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="obj1">click me</div>
<div class="obj2"></div>
I was trying to create a similar effect on up and down arrows as shown in the image below but got stuck midway because of my low javascript/jquery skills.
I can't figure out how to make the text appear and then fade away on click with color change.
Here's a link to the fiddle just in case SO code snippet doesn't work
$("span").click(function() {
$("span").css("color", "grey");
$(this).css("color", "red");
});
ul > li{
list-style:none;
}
span {
cursor: pointer;
}
.fa {
font-size: 55px;
text-indent: 200px;
margin-bottom: 20px;
margin-top:30px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li><span id='select1'><i class="fa fa-long-arrow-up" aria-hidden="true"></i></span></li>
<li><span id='select2'><i class="fa fa-long-arrow-down" aria-hidden="true"></i></span></li>
</ul>
So far none of the answers have worked for me so I am asking for more help on this.
I saw this effect on reddit and I've tried many times and spent so much time but failed to get the similar effect. I'd really appreciate it if anybody could help me understand and create the exact effect.
here is my version of the solution, https://jsfiddle.net/hnk1vw6x/33/
see some explanations below.
HTML
<div class="padding-container">
<span id="rating">0</span>
<a class="arrow fa fa-arrow-up" data-animation-text="Nice!" data-value="1"></a><br/>
<a class="arrow fa fa-arrow-down" data-animation-text="Troll" data-value="-1"></a>
</div>
CSS
.padding-container {
width: 60px;
margin: 100px;
}
#rating {
float: right;
font-size: 2.1em;
width: auto;
}
a.arrow {
display: inline-block;
position: relative;
cursor: pointer;
}
a.arrow:after {
content: attr(data-animation-text);
display: block;
position: absolute;
left: 50%;
transform: translateX(-50%);
text-align: center;
width: auto;
opacity: 0;
}
a.arrow.fa-arrow-up {
color: #FF0000;
}
a.arrow.fa-arrow-down {
color: #0000FF;
}
a.arrow.fa-arrow-up:after {
bottom: 100%;
}
a.arrow.fa-arrow-down:after {
top: 100%;
}
a.arrow.animate.fa-arrow-up:after {
animation-name: slideup, bounce;
animation-duration: 3s;
}
a.arrow.animate.fa-arrow-down:after {
animation-name: slidedown, bounce;
animation-duration: 3s;
}
#keyframes slideup {
from {
bottom: 100%;
opacity: 1;
}
to {
bottom: 300%;
opacity: 0;
}
}
#keyframes slidedown {
from {
top: 100%;
opacity: 1;
}
to {
top: 300%;
opacity: 0;
}
}
#keyframes bounce {
from {
font-size: 1em;
}
3% {
font-size: 1.25em;
}
6% {
font-size: 0.75em;
}
9% {
font-size: 1em;
}
}
JavaScript
function arrowAnimationEndHandler(e) {
var arrow = e.target;
if (typeof arrow === 'undefined') {
return;
}
arrow.className = arrow.className.replace(/\banimate\b/,'');
}
function arrowClickHandler(e) {
var arrow = e.target;
if (typeof arrow === 'undefined') {
return;
}
arrow.className = arrow.className.replace(/\banimate\b/,'');
setTimeout(function () {
arrow.className += ' animate';
}, 0);
ratingUpdateBusinessLogic(arrow);
}
function ratingUpdateBusinessLogic(arrow) {
if (typeof ratingElement === 'undefined') {
return;
}
var ratingDelta = parseInt(arrow.getAttribute('data-value'), 10);
ratingElement.innerHTML = parseInt(ratingElement.innerHTML, 10) + ratingDelta;
}
var ratingElement = document.getElementById("rating");
var arrows = document.getElementsByClassName("arrow");
for (var i = 0; i < arrows.length; i++) {
arrows[i].addEventListener("animationend", arrowAnimationEndHandler, false);
arrows[i].addEventListener("click", arrowClickHandler, false);
}
Now little bit of explanation:
The problem is quite complex and author is asking for a complete solution rather then explanation of one aspect which is not clear. I decided to give an answer because then I can outline the software design steps, which might
help someone else to solve another complex problem.
In my opinion the key to complex tasks is the ability to split them in smaller, which in turn are easier to approach. Let's try to split this task into smaller pieces:
We need to draw two arrows and a number.
Up and down arrows should have different colors.
We need to draw the arrow tooltips/labels next to them.
We need to animate the arrow tooltips/labels on user interaction.
We need to apply our business logic (change the rating) on user input.
Now let's try to solve those smaller problems one by one:
We need to draw two arrows and a number. Well, HTML is our friend here and below is a trivial html code. I'm using font-awesome to draw the actual arrow icons.
<div class="padding-container">
<span id="rating">0</span>
<a class="arrow fa fa-arrow-up"></a>
<a class="arrow fa fa-arrow-down"></a>
</div>
We want our arrows to be positioned in a certain way on the screen, let's make the arrows inline-blocks, and add a line-break between them, also add some CSS to line up:
.padding-container {
width: 60px;
margin: 100px;
}
#rating {
float: right;
font-size: 2.1em;
width: auto;
}
a.arrow {
display: inline-block;
cursor: pointer;
}
Our arrows should have different colors. Again trivial CSS here. The colors are not 100% like in the gif, but that is the question of making the screenshot and picking the right color - you can do it yourself.
a.arrow.fa-arrow-up {
color: #FF0000;
}
a.arrow.fa-arrow-down {
color: #0000FF;
}
We need to draw the arrow tooltips/labels next to them. Ok, that starts to be interesting. Let's use the :after pseudo-element to draw our tooltips, because those tooltips are part of representation (and not content), they don't need to be reflected in the html structure.
I use :after and not :before because font-awesome is using before for the arrow icon rendering ;) Let's also use absolute positioning to place them relative to the actual arrows. That gives us the following CSS:
a.arrow {
position: relative;
}
a.arrow:after {
content: attr(data-animation-text);
display: block;
position: absolute;
left: 50%;
transform: translateX(-50%);
text-align: center;
width: auto;
}
a.arrow.fa-arrow-up:after {
bottom: 100%;
}
a.arrow.fa-arrow-down:after {
top: 100%;
}
Now, our tooltips are rendered just next to the arrows, and we have the possibility to control the content of them through html, e.g. for translation purposes.
Tooltips are also centered relative to the arrows.
We need to animate the arrow tooltips/labels on user interaction.
We can animate elements by javascript and we can also do that via CSS. Doing it via CSS is way more efficient, so unless we need to support really old browsers, let's stick to CSS.
We need to implement two animations, one is tooltip fading together with lift/drop and the second one is the tooltip bounce.
Let's what CSS has to offer:
a.arrow:after {
opacity: 0;
}
a.arrow.fa-arrow-up:after {
animation-name: slideup, bounce;
animation-duration: 3s;
}
a.arrow.fa-arrow-down:after {
animation-name: slidedown, bounce;
animation-duration: 3s;
}
#keyframes slideup {
from {
bottom: 100%;
opacity: 1;
}
to {
bottom: 300%;
opacity: 0;
}
}
#keyframes slidedown {
from {
top: 100%;
opacity: 1;
}
to {
top: 300%;
opacity: 0;
}
}
#keyframes bounce {
from {
font-size: 1em;
}
3% {
font-size: 1.25em;
}
6% {
font-size: 0.75em;
}
9% {
font-size: 1em;
}
}
Now we see a nice label animation straight after we load the page. All that was done without a single line of JavaScript so far.
But the task says we need to animate on user interaction.
Ok, let's now add some javascript. But before that we need a possibility to trigger the animation, let's trigger it using CSS class: animate, our CSS then changes like
a.arrow.animate.fa-arrow-up:after {
animation-name: slideup, bounce;
animation-duration: 3s;
}
a.arrow.animate.fa-arrow-down:after {
animation-name: slidedown, bounce;
animation-duration: 3s;
}
Note added animate class. If we now manually add the class to the HTML - we will see the animation again. But we need that to happen on user click, well that is easy:
function arrowClickHandler(e) {
var arrow = e.target;
arrow.className += ' animate';
}
var arrows = document.getElementsByClassName("arrow");
for (var i = 0; i < arrows.length; i++) {
arrows[i].addEventListener("click", arrowClickHandler, false);
}
Now, if we load the page and click the arrow - we will see the animation, but only once. We need to find a way to reset it. Let's remove the animate class on animation finish.
function arrowAnimationEndHandler(e) {
var arrow = e.target;
if (typeof arrow === 'undefined') {
return;
}
arrow.className = arrow.className.replace(/\banimate\b/,'');
}
var arrows = document.getElementsByClassName("arrow");
for (var i = 0; i < arrows.length; i++) {
arrows[i].addEventListener("animationend", arrowAnimationEndHandler, false);
}
Now, we can click the arrow and see an animation as many times as we want. But there is a problem, we can't restart the animation if it is going already.
For that we need a little trick:
function arrowClickHandler(e) {
var arrow = e.target;
if (typeof arrow === 'undefined') {
return;
}
arrow.className = arrow.className.replace(/\banimate\b/,'');
setTimeout(function () {
arrow.className += ' animate';
}, 0);
}
as long as we remote the animate class - we give the browser a chance to execute it's code and stop the animation and then we add the animate class again.
We need to apply our business logic (change the rating) on user input.
Here is no rocket science, we read current value and update it according to the values we have assigned to arrows:
function arrowClickHandler(e) {
...
ratingUpdateBusinessLogic(arrow);
}
function ratingUpdateBusinessLogic(arrow) {
if (typeof ratingElement === 'undefined') {
return;
}
var ratingDelta = parseInt(arrow.getAttribute('data-value'), 10);
ratingElement.innerHTML = parseInt(ratingElement.innerHTML, 10) + ratingDelta;
}
var ratingElement = document.getElementById("rating");
UPDATE:
solution with glyphicons would require replacing css/html classes fa fa-arrow-up and fa fa-arrow-down with corresponding glyphicon classes, i.e.: glyphicon glyphicon-arrow-up and glyphicon glyphicon-arrow-down. After little thinking I also decided to unbind the custom css from library classes and added custom arrow-up and arrow-down classes to simplify the icon library replacement:
<a class="arrow arrow-up glyphicon glyphicon-arrow-up" data-animation-text="Sick!" data-value="1"></a>
<a class="arrow arrow-down glyphicon glyphicon-arrow-down" data-animation-text="Suck!" data-value="-1"></a>
CSS
a.arrow.arrow-up {
.
}
a.arrow.arrow-down {
...
}
a.arrow.arrow-up:after {
...
}
a.arrow.arrow-down:after {
...
}
a.arrow.animate.arrow-up:after {
...
}
a.arrow.animate.arrow-down:after {
...
}
You can use jquery animate to get that effect. Try this
EDIT:
for exact effect use jquery easing plugin and give
easeOutElastic easing effect
$("#select1").click(function() {
$(".nice").css("display","block");
$(".nice").animate({
top: -10,
}, 500, "easeOutElastic", function() {
// Animation complete.
$(".nice").css({"opacity":"1", "top":"10px","display":"none"});
});
});
$("#select2").click(function(){
$(".troll").css("display","block");
$(".troll").animate({
top: 130,
}, 500,"easeOutElastic", function(){
$(".troll").css({"opacity":"1", "top":"120px","display":"none"});
});
});
ul > li{
list-style:none;
}
span {
cursor: pointer;
}
.fa {
font-size: 55px;
text-indent: 200px;
margin-bottom: 20px;
margin-top:30px;
}
.nice{
position:absolute;
top:10px;
text-indent :190px;
display:none;
}
.troll{
position:absolute;
top:120px;
text-indent : 190px;
display:none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js"></script>
<ul>
<li>
<p class="nice">Nice</p>
<span id='select1'><i class="fa fa-long-arrow-up" aria-hidden="true"></i></span></li>
<li><span id='select2'><i class="fa fa-long-arrow-down" aria-hidden="true"></i></span>
<p class="troll">Troll</p>
</li>
</ul>
Just Add the text and show/hide it with the help of fadeout and fadein property of Jquery.
Check your updated fiddle
$("span").click(function() {
if($(this).attr('id')=='select1')
{
$("#downText").fadeOut(300);
$("#upText").fadeIn(300);
}
else
{
$("#upText").fadeOut(300);
$("#downText").fadeIn(300);
}
$("span").css("color", "grey");
$(this).css("color", "red");
});
$("fa").click(function(){
$("fa").fadeTo("slow", 0.15);
});
Add a setTimeout to make the text fade out after a few milliseconds:
$("span").click(function() {
$("span").css("color", "grey");
$(this).css("color", "red");
});
$("#select1").click(function() {
$("#down").fadeOut(300);
$("#up").fadeIn(300);
setTimeout(function() {
$("#up").fadeOut(300); // fade out the up text
}, 300); // delay of 0.3s before fading out
});
$("#select2").click(function() {
$("#up").fadeOut(300);
$("#down").fadeIn(300);
setTimeout(function() {
$("#down").fadeOut(300); // fade out the down text
}, 300); // delay of 0.3s before fading out
});
jsFiddle: https://jsfiddle.net/qze7mqj4/16/
I also added a position:absolute; to the fading text so that it doesn't make the arrows "jump" around.
You can read more about setTimeout here: http://www.w3schools.com/jsref/met_win_settimeout.asp
Basically it tells the browser to execute a function after a specified number of milliseconds, in this case, we tell the browser to fadeOut() the text after 300ms.
I'm trying to make a <div> display and then fade out, on button click.
This works so long as the user waits for the fade to complete between <button> presses.
My problem is, if the <button> is clicked while the fade is ongoing, the <div> needs to immediately reappear, and then fade out.
I've managed to get it to immediately reappear, but now it doesn't fade out again.
To get an easier idea of what I'm doing, take a look at the JSFiddle I've setup.
Can anyone help me get this to fade out if clicked whilst already fading out?
I'm only targeting webkit.
<div id="saved">Saved!</div>
<button id="save">Save</button>
function save()
{
// Little "Saved!" div
var div = document.getElementById('saved');
// If still showing from previous save
if(div.style.visibility === 'visible')
{
resetTransition();
div.style.visibility = 'visible';
//div.style.opacity = 0;
console.log('reset');
}
// On transition end
div.addEventListener('webkitTransitionEnd', resetTransition);
function resetTransition()
{
// Disable transitions
div.className = 'notransition';
// Hide the div and reset the opacity
div.style.visibility = 'hidden';
div.style.opacity = 1;
// Need time to let CSS changes (^) refresh
setTimeout(function()
{
// Re-enable transitions
div.className = '';
// Remove the event listener by way of cloning
var dolly = div.cloneNode(true);
div.parentNode.replaceChild(dolly, div);
}, 1);
}
// Show the div and fade out - on timer due to "if still showing" needing
// to process first
setTimeout(function()
{
div.style.visibility = 'visible';
div.style.opacity = 0;
}, 1);
}
document.getElementById('save').addEventListener('click', save);
div#saved
{
-webkit-transition: opacity 1.25s ease-out;
-webkit-transition-delay: 0.75s;
background-color: #FFC;
/* Courtesy of http://fatcow.com/free-icons */
background-image: url('http://i.imgur.com/JMlclKE.png');
background-position: 3px 4px;
background-repeat: no-repeat;
border: 1px solid #333;
border-radius: 6px;
left: 5px;
opacity: 1;
padding: 10px 4px 10px 52px;
position: absolute;
top: 5px;
visibility: hidden;
width: 68px;
}
.notransition
{
-webkit-transition: none !important;
-webkit-transition-delay: none !important;
}
button
{
position: absolute;
top: 100px;
}
I updated your fiddle, moving the cloning to the top and clearing the timeout.
// Little "Saved!" div
clearTimeout(save.t);
var dolly = document.getElementById('saved');
// Remove the event listener by way of cloning
var div = dolly.cloneNode(true);
dolly.parentNode.replaceChild(div, dolly);
/* etc til */
save.t = setTimeout(/* */);