Как заставить раздельно работать слайдеры с одинаковыми классами?
Есть несколько слайдеров с одинаковыми классами. При взаимодействии с одним, перелисывают все остальные. Как их разделить, сохранив одинаковые классы? Унифицировать каждый слайдер классом или айди - не вариант.
Ссылка на codepen |
https://codepen.io/Malleys/pen/byQjOM?editors=1010 Вам осталось добавить обработку событии клавиатуры!
UPD Добавил обработку событии клавиатуры! |
Malleys ТОП! Спасибо большое!
|
Подскажите, пожалуйста, как исправить залипание клика? Например, если кликом потяну .slider и курсор уйдёт за пределы .slider-box, то слайдер залипает и начинает двигаться за курсором до следующего клика.
Как сделать, чтобы при выходе курсора за пределы слайда происходил "cancel"? |
Цитата:
|
Цитата:
Если как в Вашем примере, то при зажатии слайда и переводе курсора мыши за область окна (например в поле html) и возврате курсора на слайд, слайдер залипает. Так же заметил, что если навести курсор на другие слайдеры, они тоже залипают. Спасибо большое за помощь!:thanks: |
DenKuzmin17, проверьте ещё раз, я должно быть не сохранил пример, хотя там стоит автосохранение... (или вы посмотрели в тот момент, когда я что-то менял)
|
Цитата:
|
Цитата:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CodePen - Malleys JQuery Touch Slider</title> <style> * { margin: 0; padding: 0; } section { width: 100%; height: 100vh; background: #ececec; } .block { width: 500px; height: 100px; margin: 10px auto; } .slider-box { display: flex; overflow: hidden; border: 1px solid #909090; } .slider { display: flex; transition: 0.5s; } .slide { display: flex; width: 500px; height: 100px; align-items: center; justify-content: center; } /* :focus:hover { outline: none; } */ </style> </head> <body translate="no"> <section> <div class="block 1"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 3</div> <div class="slide">2 / 3</div> <div class="slide">3 / 3</div> </div> </div> </div> <hr> <div class="block 2"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 4</div> <div class="slide">2 / 4</div> <div class="slide">3 / 4</div> <div class="slide">4 / 4</div> </div> </div> </div> <hr> <div class="block 3"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 2</div> <div class="slide">2 / 2</div> </div> </div> </div> <hr> </section> <script src='https://profforma.store/assets/js/jquery.min.js'></script> <script src='https://profforma.store/assets/js/jquery.touchSwipe.min.js'></script> <script> $(function() { $('.slider').each(function() { var IMG_WIDTH = 500; var currentImg = 0; var maxImages = 3; var speed = 500; var slider = $(this); var swipeOptions = { triggerOnTouchEnd: true, swipeStatus: swipeStatus, allowPageScroll: "vertical", threshold: 75 }; slider.swipe(swipeOptions); /** * Catch each phase of the swipe. * move : we drag the div * cancel : we animate back to where we were * end : we animate to the next image */ function swipeStatus(event, phase, direction, distance) { //If we are moving before swipe, and we are going L or R in X mode, or U or D in Y mode then drag. if (phase == "move" && (direction == "left" || direction == "right")) { var duration = 0; if (direction == "left") { scrollImages((IMG_WIDTH * currentImg) + distance, duration); } else if (direction == "right") { scrollImages((IMG_WIDTH * currentImg) - distance, duration); } } else if (phase == "cancel") { scrollImages(IMG_WIDTH * currentImg, speed); } else if (phase == "end") { if (direction == "right") { previousImage(); } else if (direction == "left") { nextImage(); } } } function previousImage() { currentImg = Math.max(currentImg - 1, 0); scrollImages(IMG_WIDTH * currentImg, speed); } function nextImage() { currentImg = Math.min(currentImg + 1, maxImages - 1); scrollImages(IMG_WIDTH * currentImg, speed); } /** * Manually update the position of the slider on drag */ function scrollImages(distance, duration) { slider.css("transition-duration", (duration / 1000).toFixed(1) + "s"); //inverse the number we set in the css var value = (distance < 0 ? "" : "-") + Math.abs(distance).toString(); slider.css("transform", "translate(" + value + "px,0)"); } }) }); </script> </body> </html> |
Цитата:
|
Цитата:
|
как задать translateX через проценты? Если вместо value записываю новую переменную percent, перелистывание работает, а перетаскивание нет.
|
Malleys,
мне сложно понять, что вы пишите. |
Цитата:
|
Цитата:
|
Malleys,
попробую спросить снова, можно ли использовать методы плагина для клавиатуры или нет, в данном случае? |
Цитата:
|
Давайте по порядку...
Я использовал этот плагин, поскольку он был указан в скрипте автора, в котором поддержки клавиатуры нет! http://labs.rampinteractive.co.uk/to...mos/index.html Вы, рони, предложили это https://idangero.us/swiper/demos/ В обоих вариантах если нажать мышкой на слайд и увести нажатую мышь вне рамок слайдера, и затем отпустить, то потом когда поводить курсором отпущенной мыши по слайдеру, то он начнёт вести себя так, как будто мышь зажата. И позвольте уж тогда мне предложить... вот готовый слайдер, в котором нет таких багов... https://flickity.metafizzy.co/options.html Цитата:
|
Malleys,
ок! думал плагины одинаковы, исходил из названия. Цитата:
|
<link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.min.css"> <style> * { margin: 0; padding: 0; } section { width: 100%; height: 100vh; background: #ececec; } .block { width: 500px; height: 100px; margin: 10px auto; } .slider-box { border: 1px solid #909090; } .slider { transition: 0.5s; } .slide { display: flex; width: 500px; height: 100px; align-items: center; justify-content: center; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script> <script> $(function() { $('.slider').flickity({ prevNextButtons: false, pageDots: false }); }); </script> <section> <div class="block 1"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 3</div> <div class="slide">2 / 3</div> <div class="slide">3 / 3</div> </div> </div> </div> <hr> <div class="block 2"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 4</div> <div class="slide">2 / 4</div> <div class="slide">3 / 4</div> <div class="slide">4 / 4</div> </div> </div> </div> <hr> <div class="block 3"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 2</div> <div class="slide">2 / 2</div> </div> </div> </div> <hr> </section> |
Malleys,
:thanks: |
Цитата:
PS transition в процентах с текущим плагином можно реализовать? |
Цитата:
|
:-?
зачем это var value = (distance < 0 ? "" : "-") + Math.abs(distance).toString(); вариант без этой строки scrollImages(distance, duration) { this.slider.css("transition-duration", (duration / 1000).toFixed(1) + "s"); this.slider.css("transform", "translate(" + (100 * -distance / this.maxImages) + "%,0)"); } |
this.currentImg + 0.0025 * distance, duration"0.0025" это что? |
:write: вариант ...
if (direction == "left") { this.scrollImages( this.currentImg + distance / this.IMG_WIDTH , duration ); } else if (direction == "right") { this.scrollImages( this.currentImg - distance / this.IMG_WIDTH , duration ); } |
:write: всё в сборе ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CodePen - Malleys JQuery Touch Slider</title> <style> * { margin: 0; padding: 0; } section { width: 100%; height: 100vh; background: #ececec; } .block { width: 500px; height: 100px; margin: 10px auto; } .slider-box { display: flex; overflow: hidden; border: 1px solid #909090; } .slider { display: flex; transition: 0.5s; } .slide { display: flex; width: 500px; height: 100px; align-items: center; justify-content: center; } /* :focus:hover { outline: none; } */ </style> </head> <body translate="no"> <section> <div class="block 1"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 3</div> <div class="slide">2 / 3</div> <div class="slide">3 / 3</div> </div> </div> </div> <hr> <div class="block 2"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 4</div> <div class="slide">2 / 4</div> <div class="slide">3 / 4</div> <div class="slide">4 / 4</div> </div> </div> </div> <hr> <div class="block 3"> <div class="slider-box"> <div class="slider"> <div class="slide">1 / 2</div> <div class="slide">2 / 2</div> </div> </div> </div> <hr> </section> <script src='https://profforma.store/assets/js/jquery.min.js'></script> <script src='https://profforma.store/assets/js/jquery.touchSwipe.min.js'></script> <script> class Slider { constructor(slider) { this.IMG_WIDTH = 500; this.currentImg = 0; this.speed = 500; this.swipeStatus = this.swipeStatus.bind(this); this.keyboardHandler = this.keyboardHandler.bind(this); this.slider = $(slider); this.slider .parent() .attr("tabIndex", 0) .on("blur focus click", this.keyboardHandler) .swipe({ triggerOnTouchEnd: true, triggerOnTouchLeave: true, swipeStatus: this.swipeStatus, allowPageScroll: "vertical", threshold: 75 }); this.maxImages = this.slider.find(">*").length; } keyboardHandler(event) { if (event.type === "focus") { document.addEventListener("keydown", this.keyboardHandler); this.constructor.activeInstance = this; } else if (event.type === "blur") { document.removeEventListener("keydown", this.keyboardHandler); this.constructor.activeInstance = null; } else if (event.type === "keydown") { if (event.keyCode === 37) this.previousImage(); if (event.keyCode === 39) this.nextImage(); } else { this.slider.parent().focus(); } return true; } swipeStatus(event, phase, direction, distance) { //If we are moving before swipe, and we are going L or R in X mode, or U or D in Y mode then drag. if (phase == "move" && (direction == "left" || direction == "right")) { var duration = 0; if (direction == "left") { this.scrollImages( this.currentImg + distance / this.IMG_WIDTH , duration ); } else if (direction == "right") { this.scrollImages( this.currentImg - distance / this.IMG_WIDTH , duration ); } } else if (phase == "cancel") { this.scrollImages(this.currentImg, this.speed); } else if (phase == "end") { if (direction == "right") { this.previousImage(); } else if (direction == "left") { this.nextImage(); } } } scrollImages(distance, duration) { this.slider.css({"transition-duration" : (duration / 1000).toFixed(1) + "s", "transform" : "translate(" + (100 * -distance / this.maxImages) + "%,0)"}); } previousImage() { this.currentImg = Math.max(this.currentImg - 1, 0); this.scrollImages(this.currentImg, this.speed); } nextImage() { this.currentImg = Math.min(this.currentImg + 1, this.maxImages - 1); this.scrollImages(this.currentImg, this.speed); } } $(() => { for (const element of $(".slider")) { new Slider(element); } }); </script> </body> </html> |
Цитата:
Вот, написал собственную реализацию слайдера без той сторонней библиотеки. https://codepen.io/Malleys/pen/byQjOM?editors=0010 Теперь можно начать перетаскивать слайд и курсор мыши вывести за рамки окна браузера и оно правильно обрабатывается! Что-то не нашёл ни одной библиотеки, которые бы это учитывали. |
Malleys,
зачем эта строка? this.slider[Symbol.for("slider")] = this; или как это работает? pointer.addEventListener("start", ({ target }) => { Slider.activeElement = ( target.matches(".slider") && target || target.closest(".slider") || {})[ Symbol.for("slider")]; }); не понимаю что тут происходит, зачем нужно использовать Symbol.for("slider")? |
Цитата:
Цитата:
|
Malleys,
ещё вопрос почему на родителя this.slider.parentNode.addEventListener а не на элемент slider, ставится обработка событий? |
Malleys,
в чём смысл уникальной метки this.slider[Symbol.for("slider")] = this; почему не this.slider["slider"] = this; например? |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
Часовой пояс GMT +3, время: 13:44. |