为什么此d3代码运行会有几秒钟的延迟?

时间:2019-07-11 08:17:58

标签: d3.js initialization mouseover freeze

我将一组<span>元素添加到<div>中,并希望在将鼠标悬停在它们上时弹出。

我的代码可以工作,但是在DOM完成和处理鼠标事件之间有5(或更多)秒的延迟。 (Chrome上为d3 v3):

var popup=d3.select("body")
   .append("div")
   .attr("class","popup")
   .style("opacity",0)
   .style("overflow","auto");

var bucket=d3.select("body")
  .append("div").text("DIV")
  .attr("id","bucket");
            bucket.append("div").attr("class","xxx").text("List: ");
            document.addEventListener("DOMContentLoaded", 
   function(e) {
     var ptypes =["Pigs","Geese","Ducks","Elephants"];
     var content=[];
     for(i=0; i<ptypes.length; i++) {
       content.push({"key":ptypes[i],"data":"xxx"});
     }
     
     keys=d3.select("body").selectAll(".xxx");
     d3.select("body").select(".xxx")
       .selectAll("p")
       .data(content)
       .enter()
       .append("span")
       .html(function(d) {return "   "+d.key+"   "; })
       .on("mouseover",function(d) {
           popup.text(d.data)
            .style("opacity",0.9)
            .style("left", (d3.event.pageX) + "px")    
            .style("top", (d3.event.pageY+20) + "px");
        })
       .on("mouseout",function(d) {
           popup.style("opacity",0)
       });
});
div.popup {
    position: absolute;
    text-align: left;
    width: 200px; height: 200px; padding: 3px;
    background: lightsteelblue;
    border: 0px; border-radius: 4px;
}
<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
<style>
div.popup {
    position: absolute;
    text-align: left;
    width: 200px; height: 200px; padding: 3px;
    background: lightsteelblue;
    border: 0px; border-radius: 4px;
}
</style>
</head>
<body>
    <script>
            var popup=d3.select("body")
                    .append("div")
                    .attr("class","popup")
                    .style("opacity",0)
                    .style("overflow","auto");
            var bucket=d3.select("body")
                    .append("div").text("DIV")
                    .attr("id","bucket");
            bucket.append("div").attr("class","xxx").text("List: ");
            document.addEventListener("DOMContentLoaded", 
            function(e) {
                    var ptypes =["Pigs","Geese","Ducks","Elephants"];
                    var content=[];
                    for(i=0; i<ptypes.length; i++) {

content.push({"key":ptypes[i],"data":"xxx"});
                    }
                    keys=d3.select("body").selectAll(".xxx");
                    d3.select("body").select(".xxx")
                            .selectAll("p")
                            .data(content)
                            .enter()
                            .append("span")
                            .html(function(d) {return "   "+d.key+"   "; })
                            .on("mouseover",function(d) {
                                    popup.text(d.data)
                                    .style("opacity",0.9)
                                    .style("left", (d3.event.pageX) + "px")    
                            .style("top", (d3.event.pageY+20) + "px");
                            })
                            .on("mouseout",function(d) {
                                    popup.style("opacity",0)
                            });
            });
    </script>
</body>
</html>

该代码有效,但是在开始识别鼠标事件之前有很大的延迟(5秒或更长时间)。

1 个答案:

答案 0 :(得分:1)

没有计时问题,指针事件似乎立即起作用。问题是您的div包含了您要与之交互的元素:

enter image description here

我将不透明度设置为0.4而不是0,我们可以看到div窒息了您的交互式元素。如果将鼠标移到大象的“ ts”上,我会立即互动。将鼠标悬停在“ ts”上后,div移开,与其他元素进行交互:

var popup=d3.select("body")
   .append("div")
   .attr("class","popup")
   .style("opacity",0.4)
   .style("overflow","auto");

var bucket=d3.select("body")
  .append("div").text("DIV")
  .attr("id","bucket");
            bucket.append("div").attr("class","xxx").text("List: ");
            document.addEventListener("DOMContentLoaded", 
   function(e) {
     var ptypes =["Pigs","Geese","Ducks","Elephants"];
     var content=[];
     for(i=0; i<ptypes.length; i++) {
       content.push({"key":ptypes[i],"data":"xxx"});
     }
     
     keys=d3.select("body").selectAll(".xxx");
     d3.select("body").select(".xxx")
       .selectAll("p")
       .data(content)
       .enter()
       .append("span")
       .html(function(d) {return "   "+d.key+"   "; })
       .on("mouseover",function(d) {
           popup.text(d.data)
            .style("opacity",0.9)
            .style("left", (d3.event.pageX) + "px")    
            .style("top", (d3.event.pageY+20) + "px");
        })
       .on("mouseout",function(d) {
           popup.style("opacity",0.4)
       });
});
div.popup {
    position: absolute;
    text-align: left;
    width: 200px; height: 200px; padding: 3px;
    background: lightsteelblue;
    border: 0px; border-radius: 4px;
}
<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>

然后的解决方案是将div的pointer-events样式设置为none

var popup=d3.select("body")
   .append("div")
   .attr("class","popup")
   .style("opacity",0.4)
   .style("overflow","auto");

var bucket=d3.select("body")
  .append("div").text("DIV")
  .attr("id","bucket");
            bucket.append("div").attr("class","xxx").text("List: ");
            document.addEventListener("DOMContentLoaded", 
   function(e) {
     var ptypes =["Pigs","Geese","Ducks","Elephants"];
     var content=[];
     for(i=0; i<ptypes.length; i++) {
       content.push({"key":ptypes[i],"data":"xxx"});
     }
     
     keys=d3.select("body").selectAll(".xxx");
     d3.select("body").select(".xxx")
       .selectAll("p")
       .data(content)
       .enter()
       .append("span")
       .html(function(d) {return "   "+d.key+"   "; })
       .on("mouseover",function(d) {
           popup.text(d.data)
            .style("opacity",0.9)
            .style("left", (d3.event.pageX) + "px")    
            .style("top", (d3.event.pageY+20) + "px");
        })
       .on("mouseout",function(d) {
           popup.style("opacity",0.4)
       });
});
div.popup {
    position: absolute;
    text-align: left;
    width: 200px; height: 200px; padding: 3px;
    background: lightsteelblue;
    border: 0px; border-radius: 4px;
    pointer-events:none;
}
<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>