自适应滑块的问题

时间:2017-01-24 08:28:30

标签: javascript slider

在尝试使用纯JS创建自适应滑块时遇到了一些问题。

任务是:

  • 在移动设备中,滑块仅显示文本信息或一小块幻灯片
  • 当宽度增加时(通过媒体查询),滑块变大并显示更多内容。

我的代码是:

// просто запрашиваем 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>

但问题在于“data-pos”的固定值。如何根据媒体查询通过JS(例如)更改这些属性?

或者是否有另一种制作自适应滑块的方法?

1 个答案:

答案 0 :(得分:1)

您可以通过一些小调整来重新定位滑块。不使用固定像素位置,而是使用百分比。首先,我们将data-pos属性更改为表示幻灯片编号的简单整数。

<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>

然后根据幻灯片编号将wrapper.style.left位置重新定义为百分比。

var position = link.getAttribute("data-pos"); //забираем у него data-pos
wrapper.style.left = `-${position * 100}%`;

例如,对于带有data-pos=2的幻灯片#2,wrapper.style.left将为-200%,导致滑块滑动到第二张幻灯片。这应该适用于屏幕尺寸。

// просто запрашиваем 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>