如何旋转元素并只显示其中的4个

How can I rotate the elements and only show 4 of them?

本文关键字:显示 4个 元素 何旋转 旋转      更新时间:2023-09-26

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

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

// 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');
.member {
      display: none;
      width: 100px;background: #FF0000;box-sizing: border-box;
    }
<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>

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

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这样沉重框架的解决方案,我会很高兴。提前谢谢!

这是一个高效且小型的解决方案,没有外部库
(我尽量靠近你的代码)

解决方案的一些背景

  • 通过父容器css类teambox的css overflow:hidden;来实现成员的Hidding。(宽度设置为构件宽度的四倍)
  • 循环使用insertBefore命令完成,该命令移动节点

    // 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);
    }
.member {
  width: 100px;
  background: #FF0000;
  box-sizing: border-box;
  float:left;
  height:25px;
}
.teambox{
  width:400px;
  border:solid 1px black;
  overflow:hidden;
  height:22px;
}
<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 -->

简短说明

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

您有很多滑块组件,它们没有任何依赖关系。

看看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,请查看上面的链接。