d3.js 和 document.onReady
我刚刚开始使用 d3.js ,有一个细节完全让我困惑:如何我是否只在 DOM 准备好接收输入后才执行代码?
当然,我可以使用 jQuery 之类的东西,但这似乎有点过分了。
在我遇到的每个 d3.js 示例中似乎没有什么特别的< code>document.onReady() 类型的例程,但所有示例都可以完美运行。然而,当我测试代码时,如果在 DOM 准备好之前执行,代码将完全失败(将我的代码放入 window.onload
中证实了这一点)。
什么给?
I'm just getting started with d3.js and there is one detail which is completely eluding me: how do I have my code execute only after the DOM is ready to receive input?
I could, of course, use something like jQuery but that seems excessive.
In every d3.js example I've encountered there seems to be no special document.onReady()
type of routine, yet all the examples work flawlessly. When testing code on my end, however, the code totally fails if executed before the DOM is ready (throwing my code into a window.onload
confirms this).
What gives?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您会在他们的示例中注意到,他们的 javascript 位于所使用的任何 html 元素下方,以便在开始执行 javascript 之前加载 dom 的一部分。
只需将 javascript 放在正文的底部通常就足够了。
You'll notice in their examples that their javascript is below any of the html elements that is utilized so that part of the dom is loaded before it starts executing the javascript.
Simply putting your javascript at the bottom of the body is usually good enough.
有时您不能依赖 DIV / HTML 元素放置,例如当您需要将使用 D3 操作的元素动态插入到文档中时。在这种情况下,一种解决方案是监视文档中的 DOMNodeInserted 事件并在回调中插入 D3 代码(不过我相信这排除了 9 之前的 IE 版本)。这是一个使用 jQuery 的示例:
Sometimes you can't rely on the DIV / HTML element placing, for instance when you need to insert the element manipulated with D3 dynamically into the document. In such situations one solution is to monitor the document for DOMNodeInserted events and insert the D3 code in a callback (I believe this rules out IE versions prior to 9 though). Here's an example with jQuery:
标记为正确的答案对我不起作用,实际上是错误的。这是某种黑客行为,不应被视为正确答案。同样,您可以在 setTimeout(function() { .. }, 1000) 内执行代码。它更加可靠,因为您可以设置延迟:-/
在我的例子中,我需要等待所有元素被处理才能知道它们的实际尺寸。当它们没有被建造、加工和完成时,数字就不正确。
更新。这是正确的答案:
很可能您使用诸如 d3.json() 之类的异步调用来获取构建 DOM 的数据,这就是为什么它需要一些时间。由于异步调用是非阻塞的,因此即使在异步调用完成之前,您的后续代码也会被调用,从而导致问题,这就是您发布此问题的原因。
因此,您尝试通过在 D3 或其他任何地方查找某些内容来解决此问题,这会告诉您 D3 异步调用已完成,现在您可以执行下一步操作。有些人建议进行同步 ajax 调用。这是非常错误的。异步调用被创建为异步的。
你真正需要做的是改变你的范式。只需将回调传递给该异步调用即可!类似的东西:
另外,看看 async.js
上面建议的绑定事件也是一个可怕的想法。您应该使用 .enter() .exit() 代替。 D3 是数据驱动的,如果您需要事件驱动的流程,那么只需使用 jQuery 或 vanilla JS!
The answer marked as correct didn't work for me, and is actually wrong. It's some kind of a hack and should not be considered as a correct answer. Same way you could just execute your code inside setTimeout(function() { .. }, 1000). It is even more reliable as you can set the delay :-/
In my case I needed to wait for all elements to be processed in order to know their actual dimensions. When they are not built, processed and done, the numbers were not correct.
UPDATED. Here is the correct answer:
Most probably you get your data for building DOM using some async call like d3.json() and that's why it takes some time. As async call is non-blocking, then your subsequent code gets invoked even before the async call finishes, causing problems, and this is the reason why you posted this question.
So you are trying to solve this by looking for something in D3 or anywhere else, that would tell you that D3 async call is finished and now you can do your next thing. Some people suggest making sync ajax call. This is awfully WRONG. Async calls are created to be async.
What you actually need to do is to change your paradigm. Just pass a callback to that async call and that's it! Something like that:
Also, take a look at async.js
Binding events as suggested above is also a horrible idea. You should use .enter() .exit() instead. D3 is Data driven, if you need event-driven flow, then just use jQuery or vanilla JS!
您可以将 onload 事件放在 body 中,并将所有 d3js 代码放在一个函数中。例如:
在您的 javascript 中,插入以下内容:
只需将完整的 d3 示例代码粘贴到该函数中即可。 onload 事件将在 DOM 准备好后发生。
You can put an onload event at body and put all d3js code in a function. For example:
And in your javascript, insert this:
Just paste the full d3 example code inside this function. The onload event will happen after the DOM is ready.