Reputation: 101
I have some problems while trying to make an adaptive slider with only pure JS.
The task is:
My code is:
// просто запрашиваем DOM... будто просим разрешение у босса!
var links = document.querySelectorAll(".itemLinks");
var wrapper = document.querySelector("#wrapper");
var left = document.getElementById("arrow_left");
var right = document.getElementById("arrow_right");
// activeLink обеспечивает метку для активного элемента
var activeLink = 0;
// устанавливаем отслеживание событий
for (var i = 0; i < links.length; i++) {
var link = links[i];
link.addEventListener('click', setClickedItem, false); //при клике даём setClickedItem, которая уже изменяет позицию
// определяем элемент для activeLink
link.itemID = i;
}
// устанавливаем первый элемент в качестве активного
links[activeLink].classList.add("active"); //добавляем активную ссылку к первому элементу
function setClickedItem(e) {
removeActiveLinks();
var clickedLink = e.target;
activeLink = clickedLink.itemID; //забираем itemID
changePosition(clickedLink); //вызываем changePosition с переданным атрибутом
}
function removeActiveLinks() { //удаляем активную ссылку
for (var i = 0; i < links.length; i++) {
links[i].classList.remove("active");
}
}
// Обработчик изменяет позицию слайдера, после того, как мы убедились,
// что в качестве активной обозначена нужная нам ссылка.
function changePosition(link) {
link.classList.add("active"); //добавляем нужной ссылке класс active
var position = link.getAttribute("data-pos"); //забираем у него data-pos
wrapper.style.left = position; //передаем data-pos в left у wrapper, перемещая его на нужное место
}
function arrowPositionForward() {
var link = document.querySelector(".active");
var position = link.getAttribute("data-pos");
var positions = ["0px", "-550px", "-1100px", "-1650px"]; //забираем у него data-pos
for(var i = 0; i<=positions.length; i++) {
if(position == positions[i]) {
removeActiveLinks();
var new_position = positions[i+1];
wrapper.style.left = new_position;
new_link = document.querySelector("[data-pos='"+new_position+"']");
new_link.classList.add("active");
return;
}
}
}
function arrowPositionBackward(){
var link = document.querySelector(".active");
var position = link.getAttribute("data-pos");
console.log(position);
var positions = ["0px", "-550px", "-1100px", "-1650px"];
for(var i = 0; i<=positions.length; i++) {
if(position == positions[i]){
removeActiveLinks();
var new_position = positions[i-1];
wrapper.style.left = new_position;
new_link = document.querySelector("[data-pos='"+new_position+"']");
new_link.classList.add("active");
return;
}
}
}
left.addEventListener('click', function(event){
event.preventDefault();
arrowPositionForward();
})
right.addEventListener('click', function(event){
event.preventDefault();
arrowPositionBackward();
})
/*Basic styles*/
#wrapper {
width: 2200px;
position: relative;
left: 0px;
transition: left .5s ease-in-out;
}
.content {
float: left;
width: 550px;
height: 350px;
white-space: normal;
background-repeat: no-repeat;
}
#itemOne {
background-color: #ADFF2F;
background-image: url("http://www.kirupa.com/images/blueSquare.png");
}
#itemTwo {
background-color: #FF7F50;
background-image: url("http://www.kirupa.com/images/yellowSquare.png");
}
#itemThree {
background-color: #1E90FF;
background-image: url("http://www.kirupa.com/images/pinkSquare.png");
}
#itemFour {
background-color: #DC143C;
background-image: url("http://www.kirupa.com/images/graySquare.png");
}
#contentContainer {
width: 550px;
height: 350px;
border: 5px black solid;
overflow: hidden;
}
#navLinks {
text-align: center;
width: 550px;
}
#navLinks ul {
margin: 0px;
padding: 0px;
display: inline-block;
margin-top: 6px;
}
#navLinks ul li {
float: left;
text-align: center;
margin: 10px;
list-style: none;
cursor: pointer;
background-color: #CCCCCC;
padding: 5px;
border-radius: 50%;
border: black 5px solid;
}
#navLinks ul li:hover {
background-color: #FFFF00;
}
#navLinks ul li.active {
background-color: #333333;
color: #FFFFFF;
outline-width: 7px;
}
#navLinks ul li.active:hover {
background-color: #484848;
color: #FFFFFF;
}
<a id="arrow_left" href="">Arrow left</a>
<div id="contentContainer">
<div id="wrapper">
<div id="itemOne" class="content">
</div>
<div id="itemTwo" class="content">
</div>
<div id="itemThree" class="content">
</div>
<div id="itemFour" class="content">
</div>
</div>
</div>
<div id="navLinks">
<ul>
<li class="itemLinks" data-pos="0px"></li>
<li class="itemLinks" data-pos="-550px"></li>
<li class="itemLinks" data-pos="-1100px"></li>
<li class="itemLinks" data-pos="-1650px"></li>
</ul>
</div>
<a href="" id="arrow_right">Arrow right</a>
But the problem is in fixed values of "data-pos". How can I change these attributes via JS (for example) depending on media-queries?
Or is there another way to make an adaptive slider?
Upvotes: 0
Views: 70
Reputation: 62773
You might be able to get by with a small tweak to how you reposition the slider. Instead of using fixed pixel positions, use percentages. First we'll change the data-pos
attribute to a simple integer representing the slide number.
<ul>
<li class="itemLinks" data-pos="0"></li>
<li class="itemLinks" data-pos="1"></li>
<li class="itemLinks" data-pos="2"></li>
<li class="itemLinks" data-pos="3"></li>
</ul>
Then redefine the wrapper.style.left
position as a percentage based on the slide number.
var position = link.getAttribute("data-pos"); //забираем у него data-pos
wrapper.style.left = `-${position * 100}%`;
For example, for slide #2 with data-pos=2
, wrapper.style.left
will be -200%
, causing the slider to slide to the 2nd slide. This should work across screen sizes.
// просто запрашиваем DOM... будто просим разрешение у босса!
var links = document.querySelectorAll(".itemLinks");
var wrapper = document.querySelector("#wrapper");
var left = document.getElementById("arrow_left");
var right = document.getElementById("arrow_right");
// activeLink обеспечивает метку для активного элемента
var activeLink = 0;
// устанавливаем отслеживание событий
for (var i = 0; i < links.length; i++) {
var link = links[i];
link.addEventListener('click', setClickedItem, false); //при клике даём setClickedItem, которая уже изменяет позицию
// определяем элемент для activeLink
link.itemID = i;
}
// устанавливаем первый элемент в качестве активного
links[activeLink].classList.add("active"); //добавляем активную ссылку к первому элементу
function setClickedItem(e) {
removeActiveLinks();
var clickedLink = e.target;
activeLink = clickedLink.itemID; //забираем itemID
changePosition(clickedLink); //вызываем changePosition с переданным атрибутом
}
function removeActiveLinks() { //удаляем активную ссылку
for (var i = 0; i < links.length; i++) {
links[i].classList.remove("active");
}
}
// Обработчик изменяет позицию слайдера, после того, как мы убедились,
// что в качестве активной обозначена нужная нам ссылка.
function changePosition(link) {
link.classList.add("active"); //добавляем нужной ссылке класс active
var position = link.getAttribute("data-pos"); //забираем у него data-pos
wrapper.style.left = `-${position * 100}%`; //передаем data-pos в left у wrapper, перемещая его на нужное место
}
function arrowPositionForward() {
var link = document.querySelector(".active");
var position = link.getAttribute("data-pos");
var positions = ["0px", "-550px", "-1100px", "-1650px"]; //забираем у него data-pos
for(var i = 0; i<=positions.length; i++) {
if(position == positions[i]) {
removeActiveLinks();
var new_position = positions[i+1];
wrapper.style.left = new_position;
new_link = document.querySelector("[data-pos='"+new_position+"']");
new_link.classList.add("active");
return;
}
}
}
function arrowPositionBackward(){
var link = document.querySelector(".active");
var position = link.getAttribute("data-pos");
console.log(position);
var positions = ["0px", "-550px", "-1100px", "-1650px"];
for(var i = 0; i<=positions.length; i++) {
if(position == positions[i]){
removeActiveLinks();
var new_position = positions[i-1];
wrapper.style.left = new_position;
new_link = document.querySelector("[data-pos='"+new_position+"']");
new_link.classList.add("active");
return;
}
}
}
left.addEventListener('click', function(event){
event.preventDefault();
arrowPositionForward();
})
right.addEventListener('click', function(event){
event.preventDefault();
arrowPositionBackward();
})
/*Basic styles*/
#wrapper {
width: 2200px;
position: relative;
left: 0px;
transition: left .5s ease-in-out;
}
.content {
float: left;
width: 550px;
height: 350px;
white-space: normal;
background-repeat: no-repeat;
}
#itemOne {
background-color: #ADFF2F;
background-image: url("http://www.kirupa.com/images/blueSquare.png");
}
#itemTwo {
background-color: #FF7F50;
background-image: url("http://www.kirupa.com/images/yellowSquare.png");
}
#itemThree {
background-color: #1E90FF;
background-image: url("http://www.kirupa.com/images/pinkSquare.png");
}
#itemFour {
background-color: #DC143C;
background-image: url("http://www.kirupa.com/images/graySquare.png");
}
#contentContainer {
width: 550px;
height: 350px;
border: 5px black solid;
overflow: hidden;
}
#navLinks {
text-align: center;
width: 550px;
}
#navLinks ul {
margin: 0px;
padding: 0px;
display: inline-block;
margin-top: 6px;
}
#navLinks ul li {
float: left;
text-align: center;
margin: 10px;
list-style: none;
cursor: pointer;
background-color: #CCCCCC;
padding: 5px;
border-radius: 50%;
border: black 5px solid;
}
#navLinks ul li:hover {
background-color: #FFFF00;
}
#navLinks ul li.active {
background-color: #333333;
color: #FFFFFF;
outline-width: 7px;
}
#navLinks ul li.active:hover {
background-color: #484848;
color: #FFFFFF;
}
<a id="arrow_left" href="">Arrow left</a>
<div id="contentContainer">
<div id="wrapper">
<div id="itemOne" class="content">
</div>
<div id="itemTwo" class="content">
</div>
<div id="itemThree" class="content">
</div>
<div id="itemFour" class="content">
</div>
</div>
</div>
<div id="navLinks">
<ul>
<li class="itemLinks" data-pos="0"></li>
<li class="itemLinks" data-pos="1"></li>
<li class="itemLinks" data-pos="2"></li>
<li class="itemLinks" data-pos="3"></li>
</ul>
</div>
<a href="" id="arrow_right">Arrow right</a>
Upvotes: 1