如何旋转元素并仅显示4个元素?

时间:2016-08-02 07:18:52

标签: javascript html

我想编写一个显示团队所有成员的旋转框。总共有6个成员,但该框应该只显示4个成员。使用 next prev 箭头,访问者应该能够看到其他成员。

我当前的解决方案默认情况下使所有div.member都不可见。然后它在javascript(display1-4)中设置4个全局变量,并为它们分配数字(1-4)。每个 next -click,每个显示变量递增1,如果大于6,则再次从1开始 - 分别使用 prev 。这部分有效。这是一个演示页面(我想制作一个JSFiddle,但它没有用,或者你可以看到页面here



// initial setting slider.js
      var display1 = 0;
      var display2 = 1;
      var display3 = 2;
      var display4 = 3;
      var maxno = 6;  // number of elements

      function ChangeSlide(direction) {
        if (direction == 'next') {  // arrow right
          display1 = display1 + 1;
          display2 = display2 + 1;
          display3 = display3 + 1;
          display4 = display4 + 1;
        } else {    // arrow left
          display1 = display1 - 1;
          display2 = display2 - 1;
          display3 = display3 - 1;
          display4 = display4 - 1;
        }

        // next gets higher than maxno
        if (display1 > maxno) {
          display1 = display1 - maxno;
        } else if (display2 > maxno) {
          display2 = display2 - maxno;
        } else if (display3 > maxno) {
          display3 = display3 - maxno;
        } else if (display4 > maxno) {
          display4 = display4 - maxno;
        }

        // prev gets lower than 1
        if (display1 < 1) {
          display1 = display1 + maxno;
        } else if (display2 < 1) {
          display2 = display2 + maxno;
        } else if (display3 < 1) {
          display3 = display3 + maxno;
        } else if (display4 < 1) {
          display4 = display4 + maxno;
        }

        // Make all existing IDs invisible
        document.getElementById('slide1').style.display = 'none';
        document.getElementById('slide2').style.display = 'none';
        document.getElementById('slide3').style.display = 'none';
        document.getElementById('slide4').style.display = 'none';
        document.getElementById('slide5').style.display = 'none';
        document.getElementById('slide6').style.display = 'none';

        // Make specified ID visible again
        document.getElementById('slide' + display1).style.display = 'inline-block';
        document.getElementById('slide' + display2).style.display = 'inline-block';
        document.getElementById('slide' + display3).style.display = 'inline-block';
        document.getElementById('slide' + display4).style.display = 'inline-block';
      }

ChangeSlide('next');
&#13;
.member {
      display: none;
      width: 100px;background: #FF0000;box-sizing: border-box;
    }
&#13;
<p><a onclick="ChangeSlide('prev')">PREV</a> -- <a onclick="ChangeSlide('next')">NEXT</a></p>

<div class="teambox">
  <div class="member" id="slide1"><span>Member 1</span></div>
  <div class="member" id="slide2"><span>Member 2</span></div>
  <div class="member" id="slide3"><span>Member 3</span></div>
  <div class="member" id="slide4"><span>Member 4</span></div>
  <div class="member" id="slide5"><span>Member 5</span></div>
  <div class="member" id="slide6"><span>Member 6</span></div>
</div>
&#13;
&#13;
&#13;

但是存在一个逻辑错误:如果我在 next 上点击三次,它应该按顺序显示成员:

4, 5, 6, 1

相反,它会像这样显示它们

1, 4, 5, 6

向后滑动时会发生类似的逻辑缺陷。

我的想法是相应地交换子元素,一种方法是

// move first child element (team member) to the last position 
var list = document.querySelector(".teambox");
list.appendChild(list.firstElementChild);

这使得整个订单更加混乱,特别是因为我没有一个解决办法,就像反过来一样。

如果没有像jQuery这样的重型框架的解决方案,我会很高兴。提前谢谢!

2 个答案:

答案 0 :(得分:1)

这是一个高效小巧的解决方案,没有外部库 (我尽量保持尽可能接近您的代码)

解决方案的一些背景

  • 通过父容器css-class overflow:hidden;的css teambox来隐藏成员。 (宽度设置为构件宽度的四倍)
  • 使用insertBefore命令完成cylce,移动节点

&#13;
&#13;
    // Helper Constant so that the Code can be read/understund "better"
    const AFTER_THE_LAST_ELEMENT = null; 

    function changeSlide(direction) {
      var elementToMove;
      var elements = document.querySelectorAll(".member"); 
      var parentNode = elements[0].parentNode;
      var firstElement = elements[0];
      var lastElement = elements[elements.length-1];
      
      if(direction === "next"){
        elementToMove = firstElement;
        insertBefore = AFTER_THE_LAST_ELEMENT;
      }else{
        elementToMove = lastElement;
        insertBefore = firstElement;
      }
      parentNode.insertBefore(elementToMove, insertBefore);
    }
&#13;
.member {
  width: 100px;
  background: #FF0000;
  box-sizing: border-box;
  float:left;
  height:25px;
}

.teambox{
  width:400px;
  border:solid 1px black;
  overflow:hidden;
  height:22px;
}
&#13;
<p><a onclick="changeSlide('prev')">PREV</a> -- <a onclick="changeSlide('next')">NEXT</a></p>

<div class="teambox">
  <div class="member" id="slide1"><span>Member 1</span></div>
  <div class="member" id="slide2"><span>Member 2</span></div>
  <div class="member" id="slide3"><span>Member 3</span></div>
  <div class="member" id="slide4"><span>Member 4</span></div>
  <div class="member" id="slide5"><span>Member 5</span></div>
  <div class="member" id="slide6"><span>Member 6</span></div>
</div>

<!--  tested won win7 with chrome 51+ and IE10 -->
&#13;
&#13;
&#13;

简短说明

  

document.querySelectorAll(".member") 将所有匹配作为数组返回    elements[elements.length-1] 从数组中选择最后一个元素    elements[0].parentNode 是所选元素的parentNode,需要删除特定元素
   parentNode.insertBefore(lastElement, firstElement) 在当前第一个元素之前插入lastElement。如果第一个参数是null,则将追加该元素。有关详细信息,请参阅MDN Reference

答案 1 :(得分:1)

您有许多可用的滑块组件没有任何依赖关系。

查看http://meandmax.github.io/lory/

你需要修改你的html结构有点像这样

<div class="slider js_slider">
  <div class="frame js_frame">
    <ul class="slides js_slides">
      <li class="js_slide" id="slide1"><span>Member 1</span></li>
      <li class="js_slide" id="slide2"><span>Member 2</span></li>
      <li class="js_slide" id="slide3"><span>Member 3</span></li>
      <li class="js_slide" id="slide4"><span>Member 4</span></li>
      <li class="js_slide" id="slide5"><span>Member 5</span></li>
      <li class="js_slide" id="slide6"><span>Member 6</span></li>
    </ul>
  </div>
</div>

并将其添加到您的js文件

document.addEventListener('DOMContentLoaded', function () {
    var slider = document.querySelector('.js_slider');

    lory(slider, {
        rewind: true
    });
});

请注意,您还需要一些CSS,请查看上面的链接。