22.03.2016, 00:57
|
Новичок на форуме
|
|
Регистрация: 21.03.2016
Сообщений: 4
|
|
Два слайдера. Не заканчивается анимация одного, при запуске второго
Здравствуйте.
Я, можно сказать, новичок и задался вопросом - сделать несколько одинаковых простых слайдеров на одной странице. C помощью jQuery могу сделать это быстро, но вот хочу сделать на чистом JavaScript и заодно подтянуть ООП и тут проблема. При запуске одного слайдера, а затем второго, анимация первого останавливается, я так понимаю из-за глобальных переменных?
<div class="portfolio">
<div class="case__container" id="case1">
<div class="slider-wrap">
<div class="slider">
<div style="background-color: #678" class="slide slide-first">text</div>
<div style="background-color: #f5d" class="slide">text2</div>
<div style="background-color: #8a2" class="slide">text3</div>
<div style="background-color: #149" class="slide">text4</div>
</div>
</div>
<div class="arrow arrow-left" onclick="Slider.left('case1')"></div>
<div class="arrow arrow-right active" onclick="Slider.right('case1')"></div>
</div>
<div class="case__container" id="case2">
<div class="slider-wrap">
<div class="slider">
<div style="background-color: #2f8" class="slide slide-first">text</div>
<div style="background-color: #faa" class="slide">text2</div>
<div style="background-color: #3ff" class="slide">text3</div>
<div style="background-color: #993" class="slide">text4</div>
</div>
</div>
<div class="arrow arrow-left" onclick="Slider.left('case2')"></div>
<div class="arrow arrow-right active" onclick="Slider.right('case2')"></div>
</div>
</div>
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var Slider = (function(){
var width = 1100;
var count;
var slider;
var wrap;
var position;
var tPosition;
var startTime = undefined;
return {
init : function(elem) {
slider = document.querySelector('#'+elem);
wrap = slider.querySelector('.slider');
position = +wrap.style.marginLeft.substr(0,wrap.style.marginLeft.length-2) || 0;
count = slider.querySelectorAll('div.slide').length;
},
left : function(elem) {
Slider.init(elem);
tPosition = position + width;
(position < 0) ? Slider.animateLeft(tPosition,elem) : elem.style.marginLeft = position + 'px';
},
right : function(elem) {
Slider.init(elem);
tPosition = position - width;
(position > -(count-1)*width) ? Slider.animateRight(tPosition,elem) : elem.style.marginLeft = position + 'px';
},
animateLeft : function (){
if ( startTime == undefined ){
startTime = new Date().getTime();
};
var time = new Date().getTime();
var passedPart = ((time - startTime) || 1) / 500;
if (passedPart < 1) {
wrap.style.marginLeft = position + (width * passedPart) + 'px';
requestAnimFrame(Slider.animateLeft,wrap);
}else{
startTime = undefined;
wrap.style.marginLeft = tPosition + 'px';
};
},
animateRight : function (){
if ( startTime == undefined ){
startTime = new Date().getTime();
};
var time = new Date().getTime();
var passedPart = ((time - startTime) || 1) / 500;
if (passedPart < 1) {
wrap.style.marginLeft = position - (width * passedPart) + 'px';
requestAnimFrame(Slider.animateRight,wrap);
}else{
startTime = undefined;
wrap.style.marginLeft = tPosition + 'px';
};
},
};
})();
Подтолкните дурака в правильном направлении
извините за говнокод неаккуратный код
Последний раз редактировалось Meshock, 22.03.2016 в 10:29.
Причина: Поправил немного вид
|
|
22.03.2016, 07:56
|
Кандидат Javascript-наук
|
|
Регистрация: 22.03.2016
Сообщений: 132
|
|
Если честно не понял, что Ваш код делает. Опишите, пожалуйста, поподробнее. У меня появились просто цветные полоски с надписями "text(цифра)" и все. Никакой анимации, ничего нет.
А вот интересно, что это за конструкция такая:
return{
init: function(elem){}
left: function(elem) {}
/*и т.д.*/}
Это что, обращаться к выдаваемому результату, как к полям объекта? И ведь ошибки никакой не выдает, собака!
|
|
22.03.2016, 08:13
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
Цитата:
|
А вот интересно, что это за конструкция такая:
|
функция возвращает объект, переменные width, бла-бла-бла берутся из замыкания.
Цитата:
|
И ведь ошибки никакой не выдает, собака!
|
и не должен
|
|
22.03.2016, 10:26
|
Новичок на форуме
|
|
Регистрация: 21.03.2016
Сообщений: 4
|
|
Анимации автоматической и не должно быть — рехнешься, когда на странице будут автоматом "каруселить", скажем, 5 таких огромных слайдеров
"Цветные полоски" (слайды class="slide") сдвигаются влево/вправо только после клика по дивам class="arrow". Если бы код выдавал ошибку, я бы ее исправил , но ошибок в консоли нет, поэтому не знаю куда двигаться дальше
Да, и криво начинает срабатывать при множественном нажатии на направляющих див class="arrow".
добавлю еще CSS, чтобы верстка не ехала у вас
.case__container {
height: 700px;
width: 100%;
overflow: hidden; }
/* line 15, E:/Web projects/mikejuice/src/scss/layout/_portfolio-section.scss */
.case__container .slider-wrap {
position: relative;
width: 1100px;
margin: 0 auto; }
/* line 20, E:/Web projects/mikejuice/src/scss/layout/_portfolio-section.scss */
.case__container .slider-wrap .slider {
position: absolute;
width: 4400px;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
z-index: 1; }
/* line 26, E:/Web projects/mikejuice/src/scss/layout/_portfolio-section.scss */
.case__container .slider-wrap .slider .slide {
height: 700px;
width: 1100px; }
/* line 31, E:/Web projects/mikejuice/src/scss/layout/_portfolio-section.scss */
.case__container .slider-wrap .slider .slide-first {
margin-left: 0; }
/* line 38, E:/Web projects/mikejuice/src/scss/layout/_portfolio-section.scss */
.arrow {
width: 40px;
height: 40px;
background-color: green;
position: absolute;
margin-top: 330px;
z-index: 2; }
/* line 47, E:/Web projects/mikejuice/src/scss/layout/_portfolio-section.scss */
.arrow-left {
left: 40px; }
/* line 51, E:/Web projects/mikejuice/src/scss/layout/_portfolio-section.scss */
.arrow-right {
right: 40px; }
UPD Может попробовать координаты margin-left записывать в data-* тегов и считывать как-то оттуда? Есть идеи?
Последний раз редактировалось Meshock, 22.03.2016 в 11:52.
|
|
22.03.2016, 13:30
|
Кандидат Javascript-наук
|
|
Регистрация: 22.03.2016
Сообщений: 132
|
|
По поводу Вашей задачи, ну у меня вообще стрелки не помещаются на экране по вертикали, чтобы, как Вы говорили, начать запуск второго до окончания остановки первого. Но я еще до Вашего сообщения начал понимать, что там примерно происходит. Вы говорите нет ошибок, есть! Две ошибки:
1) Uncaught TypeError: Cannot set property 'marginLeft' of undefined - происходит при нажатии на стрелку вправо, возникает в строке:
(position > -(count-1)*width) ? Slider.animateRight(tPosition,elem) : elem.style.marginLeft = position + 'px';
функции right;
2) Uncaught TypeError: wrap.getElem is not a function - возникает в строке:
wrap.getElem().style.marginLeft = tPosition + 'px';
или это последняя строка функции animateRight.
Многовато написали, задача довольно простая, мне кажется можно было проще написать.
|
|
22.03.2016, 13:36
|
Новичок на форуме
|
|
Регистрация: 21.03.2016
Сообщений: 4
|
|
Сообщение от Strongman
|
По поводу Вашей задачи, ну у меня вообще стрелки не помещаются на экране по вертикали, чтобы, как Вы говорили, начать запуск второго до окончания остановки первого. Но я еще до Вашего сообщения начал понимать, что там примерно происходит. Вы говорите нет ошибок, есть! Две ошибки:
1) Uncaught TypeError: Cannot set property 'marginLeft' of undefined - происходит при нажатии на стрелку вправо, возникает в строке:
(position > -(count-1)*width) ? Slider.animateRight(tPosition,elem) : elem.style.marginLeft = position + 'px';
функции right;
2) Uncaught TypeError: wrap.getElem is not a function - возникает в строке:
wrap.getElem().style.marginLeft = tPosition + 'px';
или это последняя строка функции animateRight.
Многовато написали, задача довольно простая, мне кажется можно было проще написать.
|
Я утром исправил код, который привел в первом сообщении: забыл убрать wrap. getElem().style.marginLeft.
Но множественное нажатие на любую из стрелок все так же ломает анимацию. Думаю куда загрузить, чтобы вы живой пример глянули...
UPD Можно пощупать тут http://meshock.github.io/mj/
Последний раз редактировалось Meshock, 22.03.2016 в 15:17.
|
|
22.03.2016, 16:53
|
Кандидат Javascript-наук
|
|
Регистрация: 22.03.2016
Сообщений: 132
|
|
А, ну дак нормально работает, остается только убрать блевотный зеленый цвет с кнопок и нарисовать в фотошопе красивые кнопки, как в Эксплорере, т.е. нужно стыбзить их оттуда. Для того, чтобы нажать на слайдер снизу, пока идет верхний, должна быть очень хорошая реакция. Так вообще это нереально сделать. Можно увеличить скорость прокрутки, чтобы это было вообще нереально сделать.
Можете, кстати, про заблокировать нижнюю кнопку пока идет верхний слайдер, ну и наоборот.
|
|
22.03.2016, 17:34
|
Новичок на форуме
|
|
Регистрация: 21.03.2016
Сообщений: 4
|
|
Сообщение от Strongman
|
А, ну дак нормально работает, остается только убрать блевотный зеленый цвет с кнопок и нарисовать в фотошопе красивые кнопки, как в Эксплорере, т.е. нужно стыбзить их оттуда. Для того, чтобы нажать на слайдер снизу, пока идет верхний, должна быть очень хорошая реакция. Так вообще это нереально сделать. Можно увеличить скорость прокрутки, чтобы это было вообще нереально сделать.
Можете, кстати, про заблокировать нижнюю кнопку пока идет верхний слайдер, ну и наоборот.
|
А еже ли потыкать несколько раз быстро на кнопку? На том же jQuery тыкни дважды - он сделает анимацию один раз, потом за ним сделает второй раз, без глюков с высчитыванием конечной позиции
|
|
|
|