CSS 过渡不适用于动态集
CSS transition not working on dynamic set
我在为简单的 JavaScript 幻灯片轮播使用 CSS transition
属性时遇到问题。
旋转木马工作正常,但 CSS transition
没有按预期工作。我在这里遗漏了什么吗?
这是一个JS Bin
HTML
<div id="slider-wrapper">
<ul>
<li data-active="true">Slide one</li>
<li data-active="false">Slide two</li>
<li data-active="false">Slide three</li>
</ul>
</div>
CSS
#slider-wrapper {
float: left;
width: 500px;
border: thin dotted;
/* overflow-x: hidden; */
height: 100px;
}
#slider-wrapper ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
height: 100px;
}
#slider-wrapper ul li {
list-style-type: none;
margin: 0;
width: 100%;
clear: both;
height: 100px;
float: left;
display: none;
margin-left: 100%;
}
#slider-wrapper ul li[data-active='true'] {
display: block !important;
margin: 0 !important;
transition: margin 1s;
}
JavaScript
// get slide deck (returns ul)
var slideDeck = document.getElementById('slider-wrapper').children[0];
/** slideIndex
* @param integer
* @return object
*/
function slideIndex(par) {
for (var i = 0; i < slideDeck.children.length; i++) {
if (slideDeck.children[i].getAttribute("data-active") == "true") {
var activeSlide = slideDeck.children[i];
var slideIndex;
// previous slide
if (par == -1) {
// if currently on first slide
if (i == 0) {
slideIndex = slideDeck.children.length - 1;
}
else {
slideIndex = i - 1;
}
}
// current slide
else if (par == 0) {
slideIndex = i;
}
// next slide
else if (par == 1) {
// if currently on last slide
if (i == slideDeck.children.length - 1) {
slideIndex = 0;
}
else {
slideIndex = i + 1;
}
}
return {
el: slideDeck.children[slideIndex],
index: slideIndex
};
}
}
}
// run a timeout loop to linear transgression
setInterval(function() {
// get slides
var currentSlideElement = slideIndex(0).el;
var previousSlideElement = slideIndex(-1).el;
var nextSlideElement = slideIndex(1).el;
currentSlideElement.setAttribute("data-active", "false");
nextSlideElement.setAttribute("data-active", "true");
console.log('ok');
}, 5500);
尝试将转换放在所有 li
中,而不是只放在活动中。
#slider-wrapper ul li {
list-style-type: none;
margin: 0;
width: 100%;
clear: both;
height: 100px;
float: left;
display: none;
margin-left: 100%;
transition: margin 1s ease-in-out;
}
如我的评论所述:
You have a different display
value for each state. Even though you are trying to transition just the margin
, the display
change will affect it and nullify your margin
.
您应该尝试使用 translate
和 opacity
,因为无论如何您都有固定的高度(如果这应该是基于内容的流动性,这种解决方案有点崩溃,但那是不是问题的一部分,所以我假设没关系。
// get slide deck (returns ul)
var slideDeck = document.getElementById('slider-wrapper').children[0];
/** slideIndex
* @param integer
* @return object
*/
function slideIndex(par) {
for (var i = 0; i < slideDeck.children.length; i++) {
if (slideDeck.children[i].getAttribute("data-active") == "true") {
var activeSlide = slideDeck.children[i];
var slideIndex;
// previous slide
if (par == -1) {
// if currently on first slide
if (i == 0) {
slideIndex = slideDeck.children.length - 1;
}
else {
slideIndex = i - 1;
}
}
// current slide
else if (par == 0) {
slideIndex = i;
}
// next slide
else if (par == 1) {
// if currently on last slide
if (i == slideDeck.children.length - 1) {
slideIndex = 0;
}
else {
slideIndex = i + 1;
}
}
return {
el: slideDeck.children[slideIndex],
index: slideIndex
};
}
}
}
// run a timeout loop to linear transgression
setInterval(function() {
// get slides
var currentSlideElement = slideIndex(0).el;
var previousSlideElement = slideIndex(-1).el;
var nextSlideElement = slideIndex(1).el;
currentSlideElement.setAttribute("data-active", "false");
nextSlideElement.setAttribute("data-active", "true");
console.log('ok');
}, 5500);
#slider-wrapper {
float: left;
width: 500px;
border: thin dotted;
/* overflow-x: hidden; */
height: 100px;
}
#slider-wrapper ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
height: inherit; /* For consistency */
position: relative; /* To contain each slide */
}
#slider-wrapper ul li {
list-style-type: none;
margin: 0;
width: 100%;
height: 100%;
/* Removed all float/margin related properties */
position: absolute;
left: 0;
top: 0;
opacity: 0; /* Hide it visually */
pointer-events: none; /* Disable interactions */
transform: translateX(100%); /* Move it away!*/
transition: all 1s; /* Feel free to make this a concise list of properties */
}
#slider-wrapper ul li[data-active='true'] {
opacity: 1; /* Show it */
pointer-events: auto; /* Restore interactions */
transform: translateX(0); /* Put it back in the centre */
}
<div id="slider-wrapper">
<ul>
<li data-active="true">Slide one</li>
<li data-active="false">Slide two</li>
<li data-active="false">Slide three</li>
</ul>
</div>
我在为简单的 JavaScript 幻灯片轮播使用 CSS transition
属性时遇到问题。
旋转木马工作正常,但 CSS transition
没有按预期工作。我在这里遗漏了什么吗?
这是一个JS Bin
HTML
<div id="slider-wrapper">
<ul>
<li data-active="true">Slide one</li>
<li data-active="false">Slide two</li>
<li data-active="false">Slide three</li>
</ul>
</div>
CSS
#slider-wrapper {
float: left;
width: 500px;
border: thin dotted;
/* overflow-x: hidden; */
height: 100px;
}
#slider-wrapper ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
height: 100px;
}
#slider-wrapper ul li {
list-style-type: none;
margin: 0;
width: 100%;
clear: both;
height: 100px;
float: left;
display: none;
margin-left: 100%;
}
#slider-wrapper ul li[data-active='true'] {
display: block !important;
margin: 0 !important;
transition: margin 1s;
}
JavaScript
// get slide deck (returns ul)
var slideDeck = document.getElementById('slider-wrapper').children[0];
/** slideIndex
* @param integer
* @return object
*/
function slideIndex(par) {
for (var i = 0; i < slideDeck.children.length; i++) {
if (slideDeck.children[i].getAttribute("data-active") == "true") {
var activeSlide = slideDeck.children[i];
var slideIndex;
// previous slide
if (par == -1) {
// if currently on first slide
if (i == 0) {
slideIndex = slideDeck.children.length - 1;
}
else {
slideIndex = i - 1;
}
}
// current slide
else if (par == 0) {
slideIndex = i;
}
// next slide
else if (par == 1) {
// if currently on last slide
if (i == slideDeck.children.length - 1) {
slideIndex = 0;
}
else {
slideIndex = i + 1;
}
}
return {
el: slideDeck.children[slideIndex],
index: slideIndex
};
}
}
}
// run a timeout loop to linear transgression
setInterval(function() {
// get slides
var currentSlideElement = slideIndex(0).el;
var previousSlideElement = slideIndex(-1).el;
var nextSlideElement = slideIndex(1).el;
currentSlideElement.setAttribute("data-active", "false");
nextSlideElement.setAttribute("data-active", "true");
console.log('ok');
}, 5500);
尝试将转换放在所有 li
中,而不是只放在活动中。
#slider-wrapper ul li {
list-style-type: none;
margin: 0;
width: 100%;
clear: both;
height: 100px;
float: left;
display: none;
margin-left: 100%;
transition: margin 1s ease-in-out;
}
如我的评论所述:
You have a different
display
value for each state. Even though you are trying to transition just themargin
, thedisplay
change will affect it and nullify yourmargin
.
您应该尝试使用 translate
和 opacity
,因为无论如何您都有固定的高度(如果这应该是基于内容的流动性,这种解决方案有点崩溃,但那是不是问题的一部分,所以我假设没关系。
// get slide deck (returns ul)
var slideDeck = document.getElementById('slider-wrapper').children[0];
/** slideIndex
* @param integer
* @return object
*/
function slideIndex(par) {
for (var i = 0; i < slideDeck.children.length; i++) {
if (slideDeck.children[i].getAttribute("data-active") == "true") {
var activeSlide = slideDeck.children[i];
var slideIndex;
// previous slide
if (par == -1) {
// if currently on first slide
if (i == 0) {
slideIndex = slideDeck.children.length - 1;
}
else {
slideIndex = i - 1;
}
}
// current slide
else if (par == 0) {
slideIndex = i;
}
// next slide
else if (par == 1) {
// if currently on last slide
if (i == slideDeck.children.length - 1) {
slideIndex = 0;
}
else {
slideIndex = i + 1;
}
}
return {
el: slideDeck.children[slideIndex],
index: slideIndex
};
}
}
}
// run a timeout loop to linear transgression
setInterval(function() {
// get slides
var currentSlideElement = slideIndex(0).el;
var previousSlideElement = slideIndex(-1).el;
var nextSlideElement = slideIndex(1).el;
currentSlideElement.setAttribute("data-active", "false");
nextSlideElement.setAttribute("data-active", "true");
console.log('ok');
}, 5500);
#slider-wrapper {
float: left;
width: 500px;
border: thin dotted;
/* overflow-x: hidden; */
height: 100px;
}
#slider-wrapper ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
height: inherit; /* For consistency */
position: relative; /* To contain each slide */
}
#slider-wrapper ul li {
list-style-type: none;
margin: 0;
width: 100%;
height: 100%;
/* Removed all float/margin related properties */
position: absolute;
left: 0;
top: 0;
opacity: 0; /* Hide it visually */
pointer-events: none; /* Disable interactions */
transform: translateX(100%); /* Move it away!*/
transition: all 1s; /* Feel free to make this a concise list of properties */
}
#slider-wrapper ul li[data-active='true'] {
opacity: 1; /* Show it */
pointer-events: auto; /* Restore interactions */
transform: translateX(0); /* Put it back in the centre */
}
<div id="slider-wrapper">
<ul>
<li data-active="true">Slide one</li>
<li data-active="false">Slide two</li>
<li data-active="false">Slide three</li>
</ul>
</div>