我之前刚问过一个类似的问题,但现在我决定把它改成一个新问题。
我使用 d3.js。名为A
的数组存储 3 种颜色,我想通过一个填充我的元素链接的循环。不幸的是,这个循环是如此之快,只有最后一个元素在屏幕上可见,这意味着只有绿色。
我怎样才能延迟这个过程?这意味着将链接变为蓝色,等待 2 秒,将它们变为红色,再等待 2 秒钟,最后将它们变成绿色?
这是我的代码...
var A = ["blue", "red", "green"]
for (var i = 0; i < A.length; i++){
link.style("stroke", function(d){
return A[i];
})
};
有很多简单的javascript答案,因为你使用的是d3,我将提供一种使用d3来实现这种效果的方法(我已经包含一个过渡(:
var svg = d3.select("body")
.append("svg")
.attr("width",400)
.attr("height",400);
var circle = svg.append("circle")
.attr("cx",100)
.attr("cy",100)
.attr("r",20)
.attr("stroke","black");
var colors = ["orange","steelblue","lawngreen","pink","darkgreen","purple"];
var i = 0
transition(i);
function transition(i) {
if (colors[i]) {
circle.transition()
.attr("fill",function() { return colors[i]; })
.duration(1000)
.each("end", function() { transition(++i) });
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
.each 方法 (v3( 现在是 .on (v4(,并在每个转换端(针对每个元素(调用,因此如果转换多个元素,则需要检查有多少元素已完成转换:
var svg = d3.select("body")
.append("svg")
.attr("width",400)
.attr("height",400);
var circles = svg.selectAll("circle")
.data([1,2])
.enter()
.append("circle")
.attr("cx",function(d) { return d * 100; })
.attr("cy",100)
.attr("r",20)
.attr("stroke","black");
var colors = ["orange","steelblue","lawngreen","pink","darkgreen","purple"];
var i = 0
transition(i);
function transition(i) {
var n = 0; // # of elements done this transition
if (colors[i]) {
circles.transition()
.attr("fill",function() { return colors[i]; })
.duration(1000)
.each("end", function() { if (++n == circles.size()) { transition(++i) } });
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
如果你不介意ES8的答案(很酷但非常新的东西(:
//a simple timer
var time=ms=>new Promise(res=>setTimeout(res,ms));
//the main function
async function loop(){
var A = ["blue", "red", "green"]
for ( var i = 0; i < A.length; i++){
link.style("stroke", function(d) { return A[i]; })
//here comes the magic part
await time(5000);//wait 5 seconds
}
}
loop();
或者使用伪递归计时器(包括 ES6 对象解构(:
(function iterate([current,...rest]){
if(!current) return;
link.style("stroke", function(d) { return current; })
setTimeout(iterate,5000,rest);
})(["blue", "red", "green"]);
摘自W3Schools:
setTimeout(function(){ alert("Hello"); }, 3000);
这样做是等待 3 秒钟,然后提醒"你好"。
使用此概念,您可以将循环重写为递归,然后使用 setTimeout 将其链接起来,延迟 2 秒左右。基本情况将是最后一种颜色,您不想在其中设置超时。
delay = 2000;
var i=0;
var handle = setInterval( function() {
if (i >= A.length) {
clearInterval(handle);
} else {
link.style("stroke", function(d) { return A[i++]});
}
}, delay);
您可以设置多个超时:
var A = ["blue", "red", "green"]
for ( var i = 0; i < A.length; i++){
setTimeout(function(){
link.style("stroke", function(d) {
return A[i];
});
}, 2000*i)
};