.attr vs .classed in D3.js
I think the classed
is a kind of conditional check for example:
To add a class, the second parameter to classed must be true, as in this code:
d3.selectAll(".bar")
.classed("my-selector", true);
To remove a class, the second parameter to classed must be false.
d3.selectAll(".bar")
.classed("my-selector", false);
To flip a class to the opposite state – remove it if it exists already, add it if it does not yet exist – you can do one of the following.
For a single element, the code might look like this:
var oneBar = d3.select(".bar")
oneBar.classed("my-selector", !oneBar.classed("my-selector"));
Both classed and attr have equal importance and attr
has other uses which classed
can not be used for.
For reference
There is no appropriate method, or recommended, or standard. Both are valid methods, and deciding which one to use depends on your specific purpose.
The main difference between classed("foo", true)
and attr("class", "foo")
is that the former will only modify the classList if it already exists...
If a value is specified, assigns or unassigns the specified CSS class names on the selected elements by setting the class attribute or modifying the classList property and returns this selection. (emphasis mine)
... while the latter will override it.
Let's show the difference in a very simple demo.
There are already paragraphs with assigned classes in the DOM. We select them and use attr("class", "someClass")
in the selection. Then, we console.log
the class of each one:
var p = d3.selectAll("p");
p.attr("class", "someClass");
p.each(function() {
console.log(d3.select(this).attr("class"))
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<p class="foo">This paragraph has a class foo</p>
<p class="bar">This paragraph has a class bar</p>
<p class="baz">This paragraph has a class baz</p>
You can see that someClass
overrides the previously existing classes.
Now the same code using classed("someClass", true)
:
var p = d3.selectAll("p");
p.classed("someClass", true);
p.each(function() {
console.log(d3.select(this).attr("class"))
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<p class="foo">This paragraph has a class foo</p>
<p class="bar">This paragraph has a class bar</p>
<p class="baz">This paragraph has a class baz</p>
As you can see, someClass
is added to the previously existing classes.