Get current CSS property value during a transition in JavaScript
Is it possible to get the current css property during a transition in JavaScript?
Yes
var timer;
function test(e) { var $this; $this = $(this); timer = setInterval(function () { console.log($this.height()); }, 500);}function untest(e) { clearInterval(timer);}
$('div').mouseenter(test).mouseleave(untest);
div{ transition: height 10s; -moz-transition: height 10s; -webkit-transition: height 10s; width: 100px; height: 100px; background-color: #00F;}
div:hover{ height: 300px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div></div>
Is it possible to get the target css property value during a css3 transition in Javascript?
That's because .css('width')
is calling getComputedStyle
on the element, which does return the transitioning value. If you did directly access the style, you would get what you just had set:
document.getElementById('transition_div').style.width
$('#transition_div').prop('style').width
$('#transition_div')[0].style.width
(updated fiddle)
Get CSS value mid-transition with native JavaScript
It is very easy to port the jQuery script from the linked thread into its vanilla JavaScript equivalent and below is a sample. The output is printed on the right side (output#op
element) once timer expires.
All that we are doing is the following:
- Attach two event handlers to the element which triggers the transition (sometimes the triggering element can be different from the one that has animation). In the other thread, the element that is triggering the transition and the one that is being transitioned is the same. Here, I have put it on two different elements just for a different demo.
- One event handler is for
mouseover
event and this creates a timer (usingsetTimeout
) which gets theopacity
andtop
value of the element that is being transitioned upon expiry of timer. - The other event handler is for
mouseleave
event to clear the timer when the user has hovered out before the specific point at which we need theopacity
andtop
value to be obtained. - Getting the
opacity
andtop
value of the element that is being transitioned can be obtained by using thewindow.getComputedStyle
method. - Unlike the demo in the other thread (which uses
setInterval
), here I have usedsetTimeout
. The difference is thatsetInterval
adds an interval and so the function is executed everyx
seconds whereas the function passed tosetTimeout
is executed only once afterx
seconds. You can use whichever fits your needs.
var wrap = document.querySelector('.wrapper'), el = document.querySelector('.with-transition'), op = document.querySelector('#op');var tmr;
wrap.addEventListener('mouseenter', function() { tmr = setTimeout(function() { op.innerHTML = 'Opacity: ' + window.getComputedStyle(el).opacity + ', Top: ' + window.getComputedStyle(el).top; }, 2500);});wrap.addEventListener('mouseleave', function() { clearTimeout(tmr);});
.wrapper { position: relative; height: 400px; width: 400px; background: yellowgreen;}.with-transition { position: absolute; top: 0px; left: 100px; width: 200px; height: 100px; background: yellow; opacity: 0; transition: all 5s linear;}.wrapper:hover .with-transition { top: 300px; opacity: 1;}output { position: absolute; top: 50px; right: 50px;}
<div class='wrapper'> <div class='with-transition'></div></div><output id='op'></output>
How to change CSS property by JS and use transition?
Firstly you are setting the transition of the --webkit-filter property, but you set the filter property.
Secondly as jneander mentioned the change is happening too quickly you should wrap it in a requestAnimationFrame or a 1ms timeout
Here is a working demo with the fixes:
let value = "15px";
let loadImg = document.getElementById("block");
let transitionDuration = "1s";
let timing = "ease-in-out";
let delay = "1s";
loadImg.style.filter = `blur(${value})`;
requestAnimationFrame(()=>{
loadImg.style.transition = `filter ${transitionDuration} ${timing} ${delay}`;
loadImg.style.filter = 'none';
});
#block {
width: 150px;
height: 150px;
background: red;
}
<div id="block"></div>
Javascript Get Element CSS Transition Stage
You can assign a property in the animation and retrieve this property value to know the animation stage. For instance, asign z-index a value between 100 and 200:
click the element to show the percentage of the animation
function showStep () { var ele = document.getElementById("test"); var step = getComputedStyle(ele).getPropertyValue("z-index") - 100; ele.innerText = step;}
#test { position: absolute; width: 400px; height: 200px; border: solid red 1px; -webkit-animation: colors 4s infinite; animation: colors 6s infinite; font-size: 80px; color: white;}
@-webkit-keyframes colors { 0% {background: red; z-index: 100;} 50% {background: blue; z-index: 150;} 100% {background: yellow; z-index: 200;}}
@keyframes colors { 0% {background: red; z-index: 100;} 50% {background: blue; z-index: 150;} 100% {background: yellow; z-index: 200;}}
<div id="test" onclick="showStep();"></div>
Cannot get CSS transition property with jquery in Firefox
Actually this is weird that transition
property is empty, but other properties that transition
consists of are accessible, so you can concatenate whole transition
value. You can get CSS properties values by using getComputedStyle
method, as well. Your console should print out every property except the first one and delay value (if you don't provide it), which is empty string:
var element = document.getElementById('transitionElement'),
style = window.getComputedStyle(element);
console.log(style.getPropertyValue('transition'));
console.log(style.getPropertyValue('transition-delay'));
console.log(style.getPropertyValue('transition-duration'));
console.log(style.getPropertyValue('transition-property'));
console.log(style.getPropertyValue('transition-timing-function'));
Always remember also to provide vendor prefixes for older versions:
#transitionElement {
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-ms-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
How to use CSS transition during accumulation on JS? (Code suddenly doesn't work)
It is probably due to internal optimisations. What is happening is that the browser is batching changes to the styles and adding them all together, even if you add them separately. This means that the left
is not being transitioned. The same happens if you try to transition any property together with display: none
to something else.
If the browser was not doing this optimisation before, they are now doing it, that's why your code is broken.
There is a simple solution to this, which is to run stock
in a callback to setTimeout, like this: setTimeout(() => this.stock(S2N), 0);
. This opts you out of the optimisation by scheduling the change at a later time (even if it's 0ms, it's still added to the queue and not executed immediately, thus the opt out). You can see this working in the snippet below. This is the easiest fix.
Another possible solution is to calculate the percentage yourself, instead of setting the display: none
to get the percentage value. As far as I understand, this behaviour is not well defined and it might change in the future. You could instead calculate the percentage of your left value like this:
Math.floor(window.innerWidth / parseInt(currentProp, 10))
You could do it during the instantiation of the Assemble
object or create some kind of logic inside the class that detects if the unit
is a percentage.
A final word of warning: transitioning left
is rather inefficient. Try transitioning the transform: translateX(value)
property. It's much better for rendering performance.
'use strict';class Assemble { constructor(elem, acc, name, unit) { this.elem = document.querySelector(elem); this.acc = acc; this.name= name; this.unit = unit; } calc() { let displayOn = this.elem.style.display; this.elem.style.display = 'none'; let currentProp = window.getComputedStyle(this.elem, null).getPropertyValue(this.name), S2N = parseInt(currentProp, 10); this.elem.style.display = displayOn; if (S2N < 100) { setTimeout(() => this.stock(S2N), 0); } } stock(value) { let digit = (value * 1) + this.acc; this.elem.style.left = digit + this.unit; this.elem.addEventListener('transitionend', this.calc.bind(this), {once: true}) console.log(this.elem.style.left); }}let proAssemble = new Assemble('.button', 10, 'left', '%');proAssemble.calc();
* { margin: 0; padding: 0;}.button { position: absolute; width: 200px; left: 0; background-color: purple; transition: left 1000ms;}
<div class="button"> test</div>
Related Topics
Iscroll 4 Not Working with Form <Select> Element iPhone Safari and Android Browser
CSS Media Query Height Greater Than Width and Vice Versa (Or How to Imitate with JavaScript)
If HTML, CSS, and JavaScript Are Client-Side, Why Are They Components of a PHP File
How to Make Specific Part of a String Bold in Angular 2
JavaScript How to Check User Agent for Mobile/Tablet
How to Add a CSS Class to a Raphael Object
How to Show/Hide Big Image by Clicking on Thumbnails
Scale the Contents of a Div by a Percentage
Download Blob File from Website Inside Android Webviewclient
Window.Scrollto Not Working in Phonegap - Alternative Solution or Workaround
Tinymce Customize "File" Menubar
Is There a Limit on Length of the Key (String) in Js Object
How to Make React-Bootstrap's Dropdown Open on Mouse Hover
Expand/Collapse Mobile Navbar Without JavaScript