d3js在函数内外没有相同的行为

时间:2014-11-12 23:36:27

标签: d3.js onload

非常奇怪!! 如果我在函数内部进行d3选择,我就不会得到与外面相同的结果!跳过第一个元素!!我甚至不确定这可能是一个太空名称环境问题: - @

如果我这样做:

<!DOCTYPE html>
<html>
    <head>           
        <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
        <script>
        function start()
        {
            Selection           = d3.select("body");
            cours               = [ { titre : " 1"  }   , { titre : " 2"  }   , { titre : " 3"  }   ]   ;
            Updated_selection   = Selection.data(  cours );
            Updated_selection   .enter ()
                                .append("h1")
                                .text(function(d) { return d.titre ; }    );

        }
        </script>
    </head>
    <body onload=start()></body>
</html>

我得到了最后两个而不是3个! :

2
3

但是如果我在函数外部放置相同的代码,而不调用onload:

<!DOCTYPE html>
<html>
    <head>           
        <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
        <script>

            Selection           = d3.select("body");
            cours               = [ { titre : " 1"  }   , { titre : " 2"  }   , { titre : " 3"  }   ]   ;
            Updated_selection   = Selection.data(  cours );
            Updated_selection   .enter ()
                                .append("h1")
                                .text(function(d) { return d.titre ; }    );


        </script>
    </head>
    <body></body>
</html>

然后我得到了我的三个值!

1    2    3

我错过了什么,但是什么??

1 个答案:

答案 0 :(得分:1)

第一次运行该函数时,body元素已经存在。在你的代码中,你正在做:

Selection           = d3.select("body");
cours               = [ { titre : " 1"  }   , { titre : " 2"  }   , { titre : " 3"  }   ]   ;

Updated_selection   = Selection.data(  cours );
Updated_selection   .enter ()
                    .append("h1")

当您使用.data(...)调用将数据绑定到DOM元素时,您将三个数据元素绑定到DOM元素数组。在这种情况下,您已经选择了body个标签的所有元素,并且您的DOM中已有1个正文标记。由于数组中的数据值多于D3选择中的项目,因此D3将为数据数组中的其他项创建“占位符”元素。

然后你调用.enter(),它将包含一个占位符元素数组。也就是说,它包含DOM中尚不存在的 NEW 元素。由于它只包含 NEW 元素,因此只会调用数组中的第二个和第三个数据值。

在第二种情况下,您的函数在创建body元素之前运行,因此当您执行select时,将返回不带元素的数组。然后,您将其绑定到具有3个值的数据数组。调用.enter()时,您将迭代 3 元素,而不是之前的2。这导致您观察到的差异。

我怀疑(根据你的代码)你真正想做的是:

        function start()
        {
            Selection           = d3.select("body h1");
            cours               = [ { titre : " 1"  }   , { titre : " 2"  }   , { titre : " 3"  }   ]   ;
            Updated_selection   = Selection.data(  cours );
            Updated_selection   .enter ()
                                .append("h1")
                                .text(function(d) { return d.titre ; }    );

        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body onload=start()></body>

注意,这里的区别在于d3.select("body h1")行。我正在选择所有h1元素,而不是body元素。这将导致空选择。当数据数组绑定到选择并调用.enter()时,将创建三个新占位符。

根据一般经验法则,您的d3.select(...)来电应在.append(...)来电中引用与您稍后.enter()相同的元素。这实际上是一个带有D3的模式,在你理解它之前你有必要阅读http://bost.ocks.org/mike/join/,即。读了几遍。