选择时执行修改的顺序

时间:2018-09-04 21:44:23

标签: javascript d3.js

在d3.js中,可以像下面这样链接许多调用,以修改给定选择中所有元素的方面:

mySelection.attr('someAttribute', function retrieveSomeAttributeValue (d) {
    return d.someValue;
}).style('someCssProperty', function retrieveSomeCssPropertyValue (d) {
    return d.someValue % 2;
});

现在,retrieveSomeAttributeValueretrieveSomeCssPropertyValue都将为mySelection中的每个元素调用一次。

但是,是否还指定了它们对任何给定元素的执行顺序?我在文档中找不到任何明确的内容。具体来说:对于mySelection中的任何给定元素,保证retrieveSomeAttributeValueretrieveSomeCssPropertyValue之前被调用,因为围绕前者的attr调用先于围绕style的调用{通话链中的后者?

一般而言:诸如attrstyle之类的修改功能是否按链接顺序应用?

编辑:由于我的问题范围似乎有些混乱,我将尝试澄清一下:显然,attr函数在style函数之前被调用。但是attr是否将其更改应用于每个元素,然后返回结果集合,于是style将其更改应用于每个元素?或者,例如,attrstyle是否以某种方式将它们各自的修改作为待处理的更改添加到集合对象上,以便稍后以可能不同的顺序执行?

EDIT2:由于这个问题似乎引起了一些混乱,请使用注释区域要求澄清,如果有什么特别不清楚的地方。

2 个答案:

答案 0 :(得分:2)

在摆弄DOM树时,D3往往很容易实现,而不必诉诸任何隐藏的魔术。对D3方法的许多调用或多或少将直接委托给本机DOM接口。 .attr().style()之类的方法也不例外。

由于文档可能会对读者和用户隐藏库的内部工作,因此确保自己掌握D3进行此操作的最佳方法可能是挖掘其源代码。作为示例,让我们看一下selection.attr()

根据文档:

  

# 选择 attr 名称 [,]){{3} }

     

[…]否则,如果该值是一个函数,则将为每个选定元素按顺序传递当前数据( d ),当前索引( i )和当前组( nodes ),其中 this 作为当前DOM元素( nodes [i] )。然后,该函数的返回值用于设置每个元素的属性。

这通过为调用提供两个参数来描述该方法作为setter的用法:第一个是属性的名称,第二个是回调。方法的<>源的relevant部分看起来像这样:

return this.each((value == null                          // <== For all nodes in this selection...
    ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
    ? (fullname.local ? attrFunctionNS : attrFunction)   // <== ...set to callbacks return value.
    : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));

基于如何处理名称空间(fullname.local),它将调用适当的函数attrFunctionNSattrFunctionfull看起来非常相似:

function attrFunction(name, value) {
  return function() {
    var v = value.apply(this, arguments);       // Evaluate the callback. 
    if (v == null) this.removeAttribute(name);  // Standard method call.
    else this.setAttribute(name, v);            // Standard method call.
  };
}

此调用返回的函数将在其第一行执行回调(由value引用)。根据该调用返回的值,如果该值等于null,它将删除该属性,或者将属性的值设置为回调的返回值。这两个操作分别利用两种标准的DOM API方法BothElement.removeAttribute()

从这几行很容易看出,D3不使用任何隐藏的魔术或内在状态,而是直接转发到本机DOM方法。对于相同的实现,您可以确保选择中的每个节点都将按其链接的相同顺序调用回调。

答案 1 :(得分:-2)

总是因为对attr()style()append()filter(),...的调用返回了下一个调用所依据的选择。此选择可能不同于呼叫所操作的选择。

在返回之前,将为选择中的每个元素调用回调(如果已定义)。幕后没有发生异步事情。