Zotoff
Zotoff

Reputation: 101

Problems with adaptive slider

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

Answers (1)

Brett DeWoody
Brett DeWoody

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

Related Questions