【问题标题】:javascript Counter always 1 behindjavascript 计数器总是落后 1
【发布时间】:2019-08-21 03:14:14
【问题描述】:

我正在构建一个简单的滑块,但我一生都无法弄清楚为什么我的点总是落后 1 步,如果我用简单的 + 1 来改变它,它会抛出我的滑块循环,请参阅笔会更有意义。

https://codepen.io/flashvenom/pen/RwborBy

这可行,但总是落后 1 步

counter++;
dots.querySelector("ul li:nth-child(" + counter + ")").classList.add("dwAccT--active");

这个点可以工作,但会抛出滑块循环

counter++;
counterPlus = 1 + counter;
dots.querySelector("ul li:nth-child(" + counterPlus + ")").classList.add("dwAccT--active");

【问题讨论】:

标签: javascript loops counter


【解决方案1】:

我将你的函数dwAutoPlay简化为

function dwAutoPlay(counter){  
  if(playing !== true) return;

  setTimeout(function(){
    counter++;
    dwAccUl.style.transform = "translateX(-" + counter%totalTiles + "00%)";
    dots.querySelector(".dwAccT--active").classList.remove("dwAccT--active");      
    dots.querySelector("ul li:nth-child(" + (1+counter%totalTiles) + ")")
      .classList.add("dwAccT--active");
    dwAutoPlay(counter);
  }, 3000);
} 

const accordion = document.getElementById("dwAcc");
const dwAccUl = document.getElementById("dwAccUl");
let playing = true;
let tiles = accordion.getElementsByClassName("dwAccLi");
let totalTiles = tiles.length;
console.log(totalTiles)
const dots = document.getElementById("dots");
let firstActive = accordion.firstElementChild;


//add initial active class to first slide
firstActive.classList.add("dwAccT--active");

//click dot to slide
function createHandler(n) {
  return function() {
    playing = false;
    //If active class exists
    if (document.querySelector(".dwAccT--active") !== null) {
      //remove active class from all instances
      document.querySelector(".dwAccT--active").classList.remove("dwAccT--active");
    }
    //add active class to current dot
    this.classList.add("dwAccT--active");
    //animate to slide position
    dwAccUl.style.transform = "translateX(-" + n + "00%)";
  };
}

//create dots
const createDotsUl = document.createElement("ul");
//Append ul to #dots
dots.appendChild(createDotsUl);
//For each tile add click event listener and create a dot
for (let i = 0; i < tiles.length; i++) {
  //create a dot
  let createDotsLi = document.createElement("li");
  //reference created dot
  let createdDot = createDotsUl.getElementsByTagName("li");
  //append the created dot to the parent ul
  createDotsUl.appendChild(createDotsLi);
  //remove existing active class from all dots
  document.querySelector(".dwAccT--active").classList.remove("dwAccT--active");
  //add inital active class to first dot
  document.querySelector("#dwAcc ul li:nth-child(1)").classList.add("dwAccT--active");
  //add event handler
  createdDot[i].addEventListener("click", createHandler(i));
}

//autoplay function
//start a counter
function dwAutoPlay(counter){  
      if(playing !== true) return;
 
      setTimeout(function(){
        counter++;
        dwAccUl.style.transform = "translateX(-" + counter%totalTiles + "00%)";
        dots.querySelector(".dwAccT--active").classList.remove("dwAccT--active");      
        dots.querySelector("ul li:nth-child(" + (1+counter%totalTiles) + ")")
          .classList.add("dwAccT--active");
        dwAutoPlay(counter);
      }, 3000);
} 

//initialize autoplay start
dwAutoPlay(0+0);
/*reset*/
html {box-sizing: border-box; overflow-y:scroll;}
*, *:before, *:after {box-sizing: inherit; }

body{background: #000; color: #fff; font-family: sans-serif; font-weight:300;font-size:100%; margin:0;opacity:1;padding:0;transition:1s opacity;overflow-x: hidden; -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%; }
a:focus,button:focus,input:focus,textarea:focus,:focus {outline: none;}
h1,h2,h3,h4,h5,h6, ul, li, p{margin: 0; padding: 0; -webkit-margin-before: 0;-webkit-margin-after: 0;-webkit-margin-start: 0px;-webkit-margin-end: 0px; text-align: left;}

#app {
  width: 100%;
  height: 100%;
}

/*reset end */
#dwAcc{
display: block;
float: left;
overflow: hidden;
position: relative;
max-height: 100vh;
width: 100%;
}
#dwAccUl{
  display: flex;
  flex-wrap: nowrap;
  margin: 0 auto;
  padding: 0;
  transform: translateX(0);
  transition: all ease-in-out 0.5s;
  width: auto;
}

.dwAccLi{
  flex: 0 0 auto;
  margin: 0;
  padding: 0;
  overflow: hidden;
  width: 100%;
}

.dwAccLi img {
  height: auto;
  width: 100%;
}

#dots ul{display: block; position: absolute; left: 2em; bottom: 1em; z-index: 1000; width: 320px; margin: 0; padding: 1em 0; list-style-type: none;}
#dots li{background: transparent; border: 2px solid #000; border-radius: 100%; display: block; float: left; height: 10px; margin: 0 10px 0 0; padding: 0; transition: all ease 0.3s; width: 10px;}
#dots li.dwAccT--active{background: #000;}
<!-- START SLIDER -->
<div id="dwAcc">
  <div id="dwAccUl">

    <div class="dwAccLi" style="background: #507f70 url('https://source.unsplash.com/1600x900/?mountains') no-repeat 0 0; background-size: cover;">
      <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAJCAQAAACRI2S5AAAAEElEQVR42mNkIAAYRxWAAQAG9gAKqv6+AwAAAABJRU5ErkJggg==">
    </div>

    <div class="dwAccLi" style="background: #6bb8ab url('https://source.unsplash.com/1600x900/?surf') no-repeat 0 0; background-size: cover;">
      <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAJCAQAAACRI2S5AAAAEElEQVR42mNkIAAYRxWAAQAG9gAKqv6+AwAAAABJRU5ErkJggg==">
    </div>

    <div class="dwAccLi" style="background: #a49c85 url('https://source.unsplash.com/1600x900/?city') no-repeat 0 0; background-size: cover;">
      <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAJCAQAAACRI2S5AAAAEElEQVR42mNkIAAYRxWAAQAG9gAKqv6+AwAAAABJRU5ErkJggg==">
    </div>

    <div class="dwAccLi" style="background: #d25d00 url('https://source.unsplash.com/1600x900/?sky') no-repeat 0 0; background-size: cover;">
      <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAJCAQAAACRI2S5AAAAEElEQVR42mNkIAAYRxWAAQAG9gAKqv6+AwAAAABJRU5ErkJggg==">
    </div>
    
    <div class="dwAccLi" style="background: #d25d00 url('https://source.unsplash.com/1600x900/?sand') no-repeat 0 0; background-size: cover;">
      <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAJCAQAAACRI2S5AAAAEElEQVR42mNkIAAYRxWAAQAG9gAKqv6+AwAAAABJRU5ErkJggg==">
    </div>

  </div>
  <div id="dots"></div>
</div>
<!-- END SLIDER -->

【讨论】:

  • 在 Kamil 和 Jaromanda 那里做得很好,我的计划是一旦我解决了那个小问题,就再把它分解一下,但你做得和我想象的一样好,我会用这个发布以供将来参考,很高兴看看是否有人可以将该功能变得更小,我会尽力而为,但我怀疑我会打败它。
  • 这条线是如何工作的 --- counter = (counter + 1) % totalTiles;我不完全理解 % 在做什么
  • 抱歉将正确答案更改为下面的 Jaromanda,因为您的答案很好,但假设有 5 张幻灯片
  • @Dubcode 我将5 更改为totalTiles - 现在更通用了。 %modulo operation,它给出的值从 0 到 totalTimes-1(以“循环方式”)
【解决方案2】:

使用模算术简化和固定

function dwAutoPlay(counter){
  if (playing) {
      counter = (counter + 1) % totalTiles;
        setTimeout(function(){
          dwAccUl.style.transform = "translateX(-" + counter + "00%)";
          dots.querySelector(".dwAccT--active").classList.remove("dwAccT--active");
          dots.querySelector("ul li:nth-child(" + (counter + 1) + ")").classList.add("dwAccT--active");
          dwAutoPlay(counter);
        }, 3000);
  }
}
dwAutoPlay(0);

【讨论】:

  • 谢谢,我认为你和上面的人很快就提出了非常相似和令人印象深刻的代码,干得好,非常感谢
  • 抱歉,将此更改为正确答案,因为动态 Kamils 答案假设有 5 张幻灯片
【解决方案3】:

试试这个

function dwAutoPlay(counter) {
  // When counter == 0, the first photo will show 2 cycle, so make it 1500,
  // which is half of 3000
  const delay = counter === 0 ? 1500 : 3000
  if (counter < totalTiles && playing === true) {
    counter++
    // Because the first photo don't need to change, while counter == 1, so here 
    // must -1 so it can be same position with dot.
    dwAccUl.style.transform = `translateX(-${counter - 1}00%)`
    dots.querySelector(".dwAccT--active").classList.remove("dwAccT--active")
    dots
      .querySelector(`ul li:nth-child(${counter})`)
      .classList.add("dwAccT--active")
  } else if (counter == totalTiles && playing === true) {
    counter = 0
    dwAccUl.style.transform = "translateX(0%)"
    // Add these 2 lines code to make active dot be correct postion while
    // photo from last one to first one
    dots.querySelector(".dwAccT--active").classList.remove("dwAccT--active")
    dots.querySelector(`ul li:nth-child(${1})`).classList.add("dwAccT--active")
  }
  setTimeout(function() {
    dwAutoPlay(counter)
  }, delay)
}

【讨论】:

  • 请在您的回答中描述问题是什么,以及这个 sn-p 将如何解决它,以帮助其他人理解这个答案
猜你喜欢
  • 2021-05-26
  • 2021-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 2019-08-31
  • 2020-01-02
相关资源
最近更新 更多