在滑块之间过渡时出现间隙? [像轮播一样设计 Bootstrap]
I get a gap while transition in between sliders? [Design Like Carousel Bootstrap]
最近我正在尝试设计类似 bootstrap 的旋转木马,用于 Angular 开发目的。
我领导的问题是过渡本身
正如我们所知,即使我们 return 回到第一个项目,左箭头也会继续滑动(从右到左)。所以我想知道他们是如何做到完美过渡的!
请注意,他们对其他幻灯片使用显示块,所以我用 javascript 做了一个简单的技巧来逃避显示 none 渲染问题。
最后,我不知道这是问题还是其他原因造成的,因为我是按照他们的方式做的,但我有一个问题,我的旋转木马在运输过程中出现了缝隙。
关于如何解决这个问题的任何想法?
这是代码
运行 代码并尝试按下一张图片并查看幻灯片之间的间隙。
"use strict";
(function (window) {
function carousel(selector) {
if (!(this instanceof carousel)) return new carousel(selector);
if (selector.nodeType == 1 || selector == window.document || selector == window) {
this.push(selector);
return;
}
var arr = document.querySelectorAll(selector);
arr.forEach(function (ele) {
this.push(ele);
}.bind(this))
return;
}
window.carousel = carousel;
return;
})(window);
var fn = carousel.prototype = [];
fn.default = {
"delay": 6000,
"transition": 'slide',
"startCycle": true,
"showArrows": true
};
fn.extend = function (prop) {
if (prop && typeof prop == "object") {
for (var value in prop) {
if (prop.hasOwnProperty(value)) {
this.default[value] = prop[value];
}
}
}
return;
};
fn.currPos = 0;
fn.oldPos = 0;
fn.render = function () {
// this.carouselInner.style.left = -1*this.currPos*this.carouselWidth+'px';
this.indicators[this.oldPos].classList.remove('active');
this.indicators[this.currPos].classList.add('active');
['prev', 'active'].forEach(function (e, i) {
(i == 0) ? this.items[this.oldPos].classList.add(e) : this.items[this.oldPos].classList.remove(e);
}.bind(this));
// this.items[this.oldPos].classList.add('prev')
// this.items[this.oldPos].classList.remove('active')
this.items[this.currPos].classList.add('next')
window.setTimeout(function () {
this.items[this.currPos].classList.add('active')
}.bind(this), 0.001);
window.setTimeout(function () {
this.items[this.oldPos].classList.remove('active')
this.items[this.oldPos].classList.remove('prev')
this.items[this.currPos].classList.remove('next')
}.bind(this), 600)
return;
}
fn.cycle = false;
fn.loop = null;
fn.iteration = window.setInterval.bind(window);
fn.clearIteration = window.clearInterval.bind(window);
fn.stopIteration = function () {
if (this.cycle && this.loop != null) {
this.clearIteration(this.loop);
this.cycle = false;
this.loop = null;
this.timeLine.classList.remove('animate');
}
return;
}
fn.startIteration = function () {
if (!this.cycle && this.loop == null) {
this.timeLine.classList.add('animate');
this.cycle = true;
this.loop = this.iteration(function () {
this.to();
}.bind(this), this.default.delay);
}
return;
}
fn.to = function () {
this.nextSlide();
this.timeLine.classList.remove('animate');
this.timeLine.classList.add('animate');
return;
};
fn.calculatePosition = function (number) {
this.oldPos = this.currPos;
this.currPos = number;
if (this.currPos != this.oldPos) {
if (this.currPos > this.itemsLength - 1) {
this.currPos = 0;
} else if (this.currPos < 0) {
this.currPos = this.itemsLength - 1;
}
this.render();
};
return;
}
fn.events = function () {
this.next.onclick = function () {
this.calculatePosition(this.currPos + 1);
}.bind(this);
this.prev.onclick = function () {
this.calculatePosition(this.currPos - 1);
}.bind(this);
this.indicators.forEach(function (ele, i) {
ele.onclick = function () {
this.calculatePosition(i);
}.bind(this);
}.bind(this));
// window.onresize = function(){
// this.arrangeSlides();
// this.render();
// }.bind(this);
if (this.default.startCycle == true) {
this[0].addEventListener('mouseenter', function (e) {
e.stopPropagation();
this.stopIteration();
}.bind(this), false);
this[0].addEventListener('mouseleave', function (e) {
e.stopPropagation();
this.startIteration();
}.bind(this), false);
};
return;
}
fn.arrangeSlides = function () {
this.carouselWidth = this[0].offsetWidth;
this.items.forEach(function (ele, i) {
ele.style.left = i * this.carouselWidth + 'px';
}.bind(this));
return;
}
fn.cashing = function () {
this.itemsLength = this[0].querySelectorAll('.carousel-inner .item').length;
this.next = this[0].querySelectorAll('.carousel-control.right')[0];
this.prev = this[0].querySelectorAll('.carousel-control.left')[0];
this.indicators = this[0].querySelectorAll('.carousel-indicators > li');
this.carouselWidth = this[0].offsetWidth;
this.carouselInner = this[0].querySelector('.carousel-inner');
this.items = this[0].querySelectorAll('.carousel-inner .item');
this.nextSlide = this.next.click.bind(this.next);
this.prevSlide = this.prev.click.bind(this.prev);
return;
}
fn.addTimeLine = function () {
var div = document.createElement('div');
div.className = 'timeLine animate';
this[0].appendChild(div);
this.timeLine = div;
this.timeLine.style.animationDuration = (this.default.delay / 1000) + 's';
return;
};
fn.init = function (prop) {
this.cashing();
this.extend(prop);
// this.arrangeSlides();
this.events();
if (this.default.startCycle == true) {
this.addTimeLine();
this.startIteration();
}
if (this.default.showArrows == false) {
this.next.style.display = 'none';
this.prev.style.display = 'none';
}
return this;
}
fn.apply = function (prop) {
var self = [];
this.forEach(function (ele) {
self.push(new carousel(ele).init(prop));
}.bind(this))
return {
"carouselElement": self[0][0],
"next": self[0].nextSlide,
"prev": self[0].prevSlide,
"Indicators": self[0].indicators,
"Settings": self[0].default
};
};
document.addEventListener('DOMContentLoaded', function () {
document.removeEventListener('DOMContentLoaded', arguments.calee);
carousel('.carousel').apply({
"delay": '1000',
"startCycle": false,
"showArrows": true
});
});
* {
border-size: border-box;
}
body {
background: #999;
}
.container {
margin: 0 auto;
width: 90%;
height: 400px;
background: #aaa;
}
.carousel {
position: relative;
width: 100%;
height: 100%;
border: 1px solid rgba(255, 255, 255, 0.7);
overflow: hidden;
}
.carousel ol {
list-style: none;
position: absolute;
bottom: 5px;
width: 50%;
padding: 0px;
margin: 0 25%;
text-align: center;
}
.carousel ol li {
width: 14px;
height: 14px;
display: inline-block;
border: 1px solid black;
border-radius: 50%;
position: relative;
z-index: 999;
cursor: pointer;
}
.carousel ol li:after {
transition: all .4s ease-in-out;
position: absolute;
top: 2px;
left: 2px;
content: '';
width: 10px;
height: 10px;
transform: scale(0);
display: inline-block;
border-radius: 50%;
background: rgba(0, 0, 0, 0.7);
}
.carousel ol li.active:after {
transform: scale(1);
}
.carousel .carousel-inner {
position: relative;
width: 100%;
height: 100%;
}
.carousel .carousel-inner .item {
position: absolute;
width: 100%;
height: 100%;
transition: left .6s ease-in-out;
transform: translate3d(0%, 0, 0);
float: left;
opacity: 1;
perspective: 1000px;
display: none;
}
.carousel .carousel-inner .item img {
width: 100%;
height: 100%;
}
.carousel .carousel-inner .item .carousel-caption {
position: absolute;
top: 0;
}
.carousel .carousel-inner .prev {
left: -100%;
display: block;
}
.carousel .carousel-inner .next {
left: 100%;
display: block;
}
.carousel .carousel-inner .active {
display: block;
left: 0;
opacity: 1;
}
.carousel a.carousel-control {
position: absolute;
top: 0;
right: 85%;
bottom: 0;
left: 0;
display: block;
text-decoration: none;
cursor: pointer;
}
.carousel a.carousel-control span {
pointer-events: none;
width: 100%;
text-align: center;
margin-top: 180px;
display: inline-block;
}
.carousel a.carousel-control span i {
font-size: 40px;
color: rgba(255, 255, 255, 0.5);
}
.carousel a.carousel-control:hover {
background: linear-gradient(90deg, rgba(0, 0, 0, 0.35), transparent);
}
.carousel a.carousel-control:hover i {
color: white;
}
.carousel a.carousel-control.right {
right: 0%;
left: 85%;
}
.carousel a.carousel-control.right:hover {
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.35), transparent);
}
.carousel a.carousel-control.right:hover i {
color: white;
}
.carousel .timeLine {
position: absolute;
height: 3px;
background: red;
top: 0px;
left: 0px;
right: 100%;
}
.carousel .animate {
animation-name: timeLine;
animation-iteration-count: infinite;
animation-timing-function: cubic-bezier(0, 0, 0.05, 0.85);
}
@keyframes timeLine {
0% {
background: white;
right: 100%;
}
100% {
background: red;
right: 0%;
}
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<div class="container">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
<li data-target="#carousel-example-generic" data-slide-to="2"></li>
<li data-target="#carousel-example-generic" data-slide-to="3"></li>
<li data-target="#carousel-example-generic" data-slide-to="4"></li>
<li data-target="#carousel-example-generic" data-slide-to="5"></li>
<li data-target="#carousel-example-generic" data-slide-to="6"></li>
<li data-target="#carousel-example-generic" data-slide-to="7"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="http://placehold.it/800/321" alt="...">
<div class="carousel-caption">
Hi my name is Ahmed
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/421" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/5b1" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/051" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/321" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/c31" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/9b1" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/abc" alt="...">
<div class="carousel-caption">
...
</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" role="button" data-slide="prev">
<span><i class="fa fa-chevron-left" aria-hidden="true"></i></span>
</a>
<a class="right carousel-control" role="button" data-slide="next">
<span><i class="fa fa-chevron-right" aria-hidden="true"></i></span>
</a>
</div>
</div>
我已经成功解决了我的问题。问题出在我的渲染函数中,我这样修改了它
Javascript
fn.render = function(){
this.indicators[this.oldPos].classList.remove('active');
this.indicators[this.currPos].classList.add('active'); // dont play with this
this.items[this.oldPos].classList.add('prev');
this.items[this.currPos].classList.add('next')
window.setTimeout(function(){
this.items[this.oldPos].classList.remove('active');
this.items[this.currPos].classList.add('active');
}.bind(this), 0.1);
window.setTimeout(function(){
this.items[this.oldPos].classList.remove('prev')
this.items[this.currPos].classList.remove('next')
this.underAnimate = true;
}.bind(this), 600)
return;
}
最近我正在尝试设计类似 bootstrap 的旋转木马,用于 Angular 开发目的。
我领导的问题是过渡本身
正如我们所知,即使我们 return 回到第一个项目,左箭头也会继续滑动(从右到左)。所以我想知道他们是如何做到完美过渡的!
请注意,他们对其他幻灯片使用显示块,所以我用 javascript 做了一个简单的技巧来逃避显示 none 渲染问题。
最后,我不知道这是问题还是其他原因造成的,因为我是按照他们的方式做的,但我有一个问题,我的旋转木马在运输过程中出现了缝隙。
关于如何解决这个问题的任何想法?
这是代码
运行 代码并尝试按下一张图片并查看幻灯片之间的间隙。
"use strict";
(function (window) {
function carousel(selector) {
if (!(this instanceof carousel)) return new carousel(selector);
if (selector.nodeType == 1 || selector == window.document || selector == window) {
this.push(selector);
return;
}
var arr = document.querySelectorAll(selector);
arr.forEach(function (ele) {
this.push(ele);
}.bind(this))
return;
}
window.carousel = carousel;
return;
})(window);
var fn = carousel.prototype = [];
fn.default = {
"delay": 6000,
"transition": 'slide',
"startCycle": true,
"showArrows": true
};
fn.extend = function (prop) {
if (prop && typeof prop == "object") {
for (var value in prop) {
if (prop.hasOwnProperty(value)) {
this.default[value] = prop[value];
}
}
}
return;
};
fn.currPos = 0;
fn.oldPos = 0;
fn.render = function () {
// this.carouselInner.style.left = -1*this.currPos*this.carouselWidth+'px';
this.indicators[this.oldPos].classList.remove('active');
this.indicators[this.currPos].classList.add('active');
['prev', 'active'].forEach(function (e, i) {
(i == 0) ? this.items[this.oldPos].classList.add(e) : this.items[this.oldPos].classList.remove(e);
}.bind(this));
// this.items[this.oldPos].classList.add('prev')
// this.items[this.oldPos].classList.remove('active')
this.items[this.currPos].classList.add('next')
window.setTimeout(function () {
this.items[this.currPos].classList.add('active')
}.bind(this), 0.001);
window.setTimeout(function () {
this.items[this.oldPos].classList.remove('active')
this.items[this.oldPos].classList.remove('prev')
this.items[this.currPos].classList.remove('next')
}.bind(this), 600)
return;
}
fn.cycle = false;
fn.loop = null;
fn.iteration = window.setInterval.bind(window);
fn.clearIteration = window.clearInterval.bind(window);
fn.stopIteration = function () {
if (this.cycle && this.loop != null) {
this.clearIteration(this.loop);
this.cycle = false;
this.loop = null;
this.timeLine.classList.remove('animate');
}
return;
}
fn.startIteration = function () {
if (!this.cycle && this.loop == null) {
this.timeLine.classList.add('animate');
this.cycle = true;
this.loop = this.iteration(function () {
this.to();
}.bind(this), this.default.delay);
}
return;
}
fn.to = function () {
this.nextSlide();
this.timeLine.classList.remove('animate');
this.timeLine.classList.add('animate');
return;
};
fn.calculatePosition = function (number) {
this.oldPos = this.currPos;
this.currPos = number;
if (this.currPos != this.oldPos) {
if (this.currPos > this.itemsLength - 1) {
this.currPos = 0;
} else if (this.currPos < 0) {
this.currPos = this.itemsLength - 1;
}
this.render();
};
return;
}
fn.events = function () {
this.next.onclick = function () {
this.calculatePosition(this.currPos + 1);
}.bind(this);
this.prev.onclick = function () {
this.calculatePosition(this.currPos - 1);
}.bind(this);
this.indicators.forEach(function (ele, i) {
ele.onclick = function () {
this.calculatePosition(i);
}.bind(this);
}.bind(this));
// window.onresize = function(){
// this.arrangeSlides();
// this.render();
// }.bind(this);
if (this.default.startCycle == true) {
this[0].addEventListener('mouseenter', function (e) {
e.stopPropagation();
this.stopIteration();
}.bind(this), false);
this[0].addEventListener('mouseleave', function (e) {
e.stopPropagation();
this.startIteration();
}.bind(this), false);
};
return;
}
fn.arrangeSlides = function () {
this.carouselWidth = this[0].offsetWidth;
this.items.forEach(function (ele, i) {
ele.style.left = i * this.carouselWidth + 'px';
}.bind(this));
return;
}
fn.cashing = function () {
this.itemsLength = this[0].querySelectorAll('.carousel-inner .item').length;
this.next = this[0].querySelectorAll('.carousel-control.right')[0];
this.prev = this[0].querySelectorAll('.carousel-control.left')[0];
this.indicators = this[0].querySelectorAll('.carousel-indicators > li');
this.carouselWidth = this[0].offsetWidth;
this.carouselInner = this[0].querySelector('.carousel-inner');
this.items = this[0].querySelectorAll('.carousel-inner .item');
this.nextSlide = this.next.click.bind(this.next);
this.prevSlide = this.prev.click.bind(this.prev);
return;
}
fn.addTimeLine = function () {
var div = document.createElement('div');
div.className = 'timeLine animate';
this[0].appendChild(div);
this.timeLine = div;
this.timeLine.style.animationDuration = (this.default.delay / 1000) + 's';
return;
};
fn.init = function (prop) {
this.cashing();
this.extend(prop);
// this.arrangeSlides();
this.events();
if (this.default.startCycle == true) {
this.addTimeLine();
this.startIteration();
}
if (this.default.showArrows == false) {
this.next.style.display = 'none';
this.prev.style.display = 'none';
}
return this;
}
fn.apply = function (prop) {
var self = [];
this.forEach(function (ele) {
self.push(new carousel(ele).init(prop));
}.bind(this))
return {
"carouselElement": self[0][0],
"next": self[0].nextSlide,
"prev": self[0].prevSlide,
"Indicators": self[0].indicators,
"Settings": self[0].default
};
};
document.addEventListener('DOMContentLoaded', function () {
document.removeEventListener('DOMContentLoaded', arguments.calee);
carousel('.carousel').apply({
"delay": '1000',
"startCycle": false,
"showArrows": true
});
});
* {
border-size: border-box;
}
body {
background: #999;
}
.container {
margin: 0 auto;
width: 90%;
height: 400px;
background: #aaa;
}
.carousel {
position: relative;
width: 100%;
height: 100%;
border: 1px solid rgba(255, 255, 255, 0.7);
overflow: hidden;
}
.carousel ol {
list-style: none;
position: absolute;
bottom: 5px;
width: 50%;
padding: 0px;
margin: 0 25%;
text-align: center;
}
.carousel ol li {
width: 14px;
height: 14px;
display: inline-block;
border: 1px solid black;
border-radius: 50%;
position: relative;
z-index: 999;
cursor: pointer;
}
.carousel ol li:after {
transition: all .4s ease-in-out;
position: absolute;
top: 2px;
left: 2px;
content: '';
width: 10px;
height: 10px;
transform: scale(0);
display: inline-block;
border-radius: 50%;
background: rgba(0, 0, 0, 0.7);
}
.carousel ol li.active:after {
transform: scale(1);
}
.carousel .carousel-inner {
position: relative;
width: 100%;
height: 100%;
}
.carousel .carousel-inner .item {
position: absolute;
width: 100%;
height: 100%;
transition: left .6s ease-in-out;
transform: translate3d(0%, 0, 0);
float: left;
opacity: 1;
perspective: 1000px;
display: none;
}
.carousel .carousel-inner .item img {
width: 100%;
height: 100%;
}
.carousel .carousel-inner .item .carousel-caption {
position: absolute;
top: 0;
}
.carousel .carousel-inner .prev {
left: -100%;
display: block;
}
.carousel .carousel-inner .next {
left: 100%;
display: block;
}
.carousel .carousel-inner .active {
display: block;
left: 0;
opacity: 1;
}
.carousel a.carousel-control {
position: absolute;
top: 0;
right: 85%;
bottom: 0;
left: 0;
display: block;
text-decoration: none;
cursor: pointer;
}
.carousel a.carousel-control span {
pointer-events: none;
width: 100%;
text-align: center;
margin-top: 180px;
display: inline-block;
}
.carousel a.carousel-control span i {
font-size: 40px;
color: rgba(255, 255, 255, 0.5);
}
.carousel a.carousel-control:hover {
background: linear-gradient(90deg, rgba(0, 0, 0, 0.35), transparent);
}
.carousel a.carousel-control:hover i {
color: white;
}
.carousel a.carousel-control.right {
right: 0%;
left: 85%;
}
.carousel a.carousel-control.right:hover {
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.35), transparent);
}
.carousel a.carousel-control.right:hover i {
color: white;
}
.carousel .timeLine {
position: absolute;
height: 3px;
background: red;
top: 0px;
left: 0px;
right: 100%;
}
.carousel .animate {
animation-name: timeLine;
animation-iteration-count: infinite;
animation-timing-function: cubic-bezier(0, 0, 0.05, 0.85);
}
@keyframes timeLine {
0% {
background: white;
right: 100%;
}
100% {
background: red;
right: 0%;
}
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<div class="container">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
<li data-target="#carousel-example-generic" data-slide-to="2"></li>
<li data-target="#carousel-example-generic" data-slide-to="3"></li>
<li data-target="#carousel-example-generic" data-slide-to="4"></li>
<li data-target="#carousel-example-generic" data-slide-to="5"></li>
<li data-target="#carousel-example-generic" data-slide-to="6"></li>
<li data-target="#carousel-example-generic" data-slide-to="7"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="http://placehold.it/800/321" alt="...">
<div class="carousel-caption">
Hi my name is Ahmed
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/421" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/5b1" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/051" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/321" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/c31" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/9b1" alt="...">
<div class="carousel-caption">
...
</div>
</div>
<div class="item">
<img src="http://placehold.it/800/abc" alt="...">
<div class="carousel-caption">
...
</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" role="button" data-slide="prev">
<span><i class="fa fa-chevron-left" aria-hidden="true"></i></span>
</a>
<a class="right carousel-control" role="button" data-slide="next">
<span><i class="fa fa-chevron-right" aria-hidden="true"></i></span>
</a>
</div>
</div>
我已经成功解决了我的问题。问题出在我的渲染函数中,我这样修改了它
Javascript
fn.render = function(){
this.indicators[this.oldPos].classList.remove('active');
this.indicators[this.currPos].classList.add('active'); // dont play with this
this.items[this.oldPos].classList.add('prev');
this.items[this.currPos].classList.add('next')
window.setTimeout(function(){
this.items[this.oldPos].classList.remove('active');
this.items[this.currPos].classList.add('active');
}.bind(this), 0.1);
window.setTimeout(function(){
this.items[this.oldPos].classList.remove('prev')
this.items[this.currPos].classList.remove('next')
this.underAnimate = true;
}.bind(this), 600)
return;
}