Reputation: 227
I'm having trouble figuring out why my CSS transition isn't firing when I programmatically remove a class from an element.
Essentially, I am trying to create a progressively enhanced, infinitely-scrolling carousel using pure Javascript.
The basic idea is that as the user clicks to scroll either left or right, the first or last element is plucked from the parent ul element, and either prepended or appended to the proper location, depending on the scroll-direction of the user's click.
Here is the relevant code:
HTML:
<div id="scroller">
<ul>
<li>
<a>
<img src="...">
</a>
</li>
..... more li elements
<li>
<a>
<img src="...">
</a>
</li>
</ul>
</div>
CSS:
#scroller {
position: absolute;
left: 0em;
height: 8em;
width: 400em;
}
#scroller ul {
list-style: none;
}
#scroller ul li {
overflow: hidden;
float: left;
height: 8em;
width: 8em;
transition: width 1s ease;
}
#scroller ul li.hide {
width: 0em;
}
#scroller ul li a img {
width: 8em;
}
JS (scroll right click event, for example):
/** Remove the element from the end of the list, add the hide class */
var node = this.list.removeChild(this.items[(this.items.length - 1)]);
/** Add the hide class to the node */
node.className += ' hide';
/** Insert the node at the beginning of the scroller */
this.list.insertBefore(node, this.items[0]);
/** Remove the hide class to trigger the transition animation */
node.className = node.className.replace('hide', '');
Everything is working well, in terms of the items being shifted around the ul correctly, so that is not the problem.
The issue is that the CSS transition is not being applied when the width of the li elements are changed by removing the "hide" class.
I had hoped to create a smooth scrolling effect in browsers than can support the CSS transition.
Thanks in advance for not suggesting that I use a JS library! :)
Upvotes: 0
Views: 1771
Reputation: 2305
Use a combo of setTimeout
and the transitionend
event.
Look here for more info on transitionend
:
CSS3 transition events
/** Remove the element from the end of the list, add the hide class */
one = document.getElementById('one');
two = document.getElementById('two');
list = document.getElementById('list');
/** Add the hide class to the node */
two.addEventListener('transitionend', end, false);
setTimeout(function(){
two.className += ' hide';
}, 0)
function end(){
/** Insert the node at the beginning of the scroller */
list.insertBefore(two, one);
/** Remove the hide class to trigger the transition animation */
setTimeout(function(){
two.className = two.className.replace('hide', '');
}, 0)
}
#scroller {
position: absolute;
left: 0em;
height: 8em;
width: 400em;
}
#scroller ul {
list-style: none;
}
#scroller ul li {
overflow: hidden;
float: left;
height: 8em;
width: 8em;
transition: width 1s ease;
}
#scroller ul li.hide {
width: 0em;
}
#scroller ul li a {
width: 8em;
background-color:red;
}
<div id="scroller">
<ul id="list">
<li id="one">
<a>
One
</a>
</li>
<li id="two">
<a>
Two
</a>
</li>
</ul>
</div>
Upvotes: 1