Javascript-For循环仅影响数组中的最后一个元素

时间:2019-02-28 19:43:32

标签: javascript

我正在尝试编写一个脚本,以使您指向的内容(具有foxrainbowhover类)具有异步彩虹效果。

我已经使它大部分工作了,但是不幸的是,由于某种原因,它仅影响数组中的最后一个元素。我已经在心理上多次运行了,但是找不到一个错误的地方。希望您能为您提供帮助。效果如下所示:https://jsfiddle.net/Laoderv6/

(function(){let rainbowhover = document.getElementsByClassName('foxrainbowhover');
    let rainbowelements = [];
    let hoverinterval = [];
    let hovercounters = [];

    for(let i = 0; i < rainbowhover.length; i++) {
        rainbowelements[i] = spanElementContents(rainbowhover[i]);
    }

    //Set up the wavey effect with counters.
    for(let id = 0; id < rainbowelements.length; id++) {
        for(let i = 0; i < rainbowelements[id].length; i++) {
            hovercounters[id] = [];
            hovercounters[id][i] = 0 + i;
        }
        
    }


    // Add event listeners for every item classed foxrainbowhover.
    for(let id = 0; id < rainbowhover.length; id++) {
        rainbowhover[id].addEventListener("mouseenter", function startanimation() {
            console.log('hit');
               
            hoverinterval[id] = setInterval(() => {
                for(let i = 0; i < rainbowelements[id].length; i++) {
                    rainbowelements[id][i].style.color = 'hsl(' + (hovercounters[id][i] + Math.floor(i * 1)) + ', 100%, 70%';
                    console.log(rainbowelements[id]);
                    
                    hovercounters[id][i]++;

                }
            }, 8);






        }, false);



        rainbowhover[id].addEventListener("mouseleave", function stopanimation() {
            console.log('agh');

            clearInterval(hoverinterval[id]);
            for(let i = 0; i < rainbowelements[id].length; i++) {
                rainbowelements[id][i].style.color = 'black';
            }

            
            
        }, false);
    }
})()

function spanElementContents(element) {
    let spans = [];
    let chars = [];

    chars.push(element.innerText.split(""));
    for(let i = 0; i < chars.length; i++){
        element.innerHTML = chars[i].map(function(char) {
            return '<span>' + char + "</span>";
        }).join('');
    }

    
    
    let temphtmlcollection = [].slice.call(element.children)
    for(let j = 0; j < temphtmlcollection.length; j++) {
         spans.push(temphtmlcollection[j]);
    }
    return spans;
}
body {
  background-color: black;
}

h1 {
  color: white;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
   
</head>
<body>
    <h1 class="foxrainbowhover">test1</h1>
    <h1 class="foxrainbowhover">test111</h1>
    <h1 class="foxrainbowhover">test111111</h1>





</body>
</html>

2 个答案:

答案 0 :(得分:2)

您一直在重置阵列。您需要在外部循环中对其进行初始化。 更改此:

for(let id = 0; id < rainbowelements.length; id++) {
    for(let i = 0; i < rainbowelements[id].length; i++) {
        hovercounters[id] = [];
        hovercounters[id][i] = 0 + i;
    }  
}

对此:

for(let id = 0; id < rainbowelements.length; id++) {
   hovercounters[id] = [];
   for(let i = 0; i < rainbowelements[id].length; i++) {
        hovercounters[id].push(i);
    }
}

或更简单地说:

or (let id = 0; id < rainbowelements.length; id++) {
  hovercounters[id] = rainbowelements[id].map((_, i) => i);
}

let rainbowhover = document.getElementsByClassName('foxrainbowhover');
let rainbowelements = [];
let hoverinterval = [];
let hovercounters = [];

for (let i = 0; i < rainbowhover.length; i++) {
  rainbowelements[i] = spanElementContents(rainbowhover[i]);
}

//Set up the wavy effect with counters.
for (let id = 0; id < rainbowelements.length; id++) {
  hovercounters[id] = rainbowelements[id].map((_, i) => i);
}

// Add event listeners for every item classed foxrainbowhover.
for(let id = 0; id < rainbowhover.length; id++) {
    rainbowhover[id].addEventListener("mouseenter", function startanimation() {
        hoverinterval[id] = setInterval(() => {
            for(let i = 0; i < rainbowelements[id].length; i++) {
                rainbowelements[id][i].style.color = 'hsl(' + (hovercounters[id][i] + Math.floor(i * 1)) + ', 100%, 70%';

                hovercounters[id][i]++;
            }
        }, 8);
    }, false);

    rainbowhover[id].addEventListener("mouseleave", function stopanimation() {
        clearInterval(hoverinterval[id]);
        for(let i = 0; i < rainbowelements[id].length; i++) {
            rainbowelements[id][i].style.color = 'black';
        }
    }, false);
}

function spanElementContents(element) {
  let spans = [];
  let chars = [];

  chars.push(element.innerText.split(""));
  for(let i = 0; i < chars.length; i++){
    element.innerHTML = chars[i].map(function(char) {
      return '<span>' + char + "</span>";
    }).join('');
  }

  let temphtmlcollection = [].slice.call(element.children)
  for(let j = 0; j < temphtmlcollection.length; j++) {
     spans.push(temphtmlcollection[j]);
  }
  return spans;
}
h1 {
  color: black;
}
<h1 class="foxrainbowhover">test1</h1>
<h1 class="foxrainbowhover">test111</h1>
<h1 class="foxrainbowhover">test111111</h1>

答案 1 :(得分:0)

这是在for循环内使用异步函数时发生的情况。以下是解决问题的几种方法:

  • 使用let代替var
  • 创建一个使用closure的函数并返回一个新函数
  • 使用try catchIIFE块创建新的作用域

for (let index = 0; index < 5; index++) {
  setTimeout(() => {
    console.log(index)
  }, 250);
}

功能包装器

for (let index = 0; index < 5; index++) {
  setTimeout(getFunction(index), 250);
}

function getFunction(index) {
  return function() {
    console.log(index);
  };
}

尝试捕获块

for (let index = 0; index < 5; index++) {
  try {
    throw index;
  } catch (index) {
    setTimeout(() => {
      console.log(index);
    }, 250);
  }
}

IIFE区块

for (let index = 0; index < 5; index++) {
  (function(index) {
    setTimeout(() => {
      console.log(index);
    }, 250);
  })(index);
}