Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selection does not work if "too exact"

Tags:

html

d3.js

consider the following minimal example:

<p>
    <ol id="First list">
        <li>foo</li>
        <li>bar</li>
    </ol>
    <ol id="Second list">
        <li>baz</li>
    </ol>
</p>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
    sel = d3.selectAll("ol")

    console.log(sel)
</script>

This works nicely: The selection contains one group which in turn has two elements (the two elements).

But if I change the selection to

sel = d3.select("p").selectAll("ol")

which looks "more exact" to me as it uses the more accurate address, the selection returns one group which is empty (that is obviously wrong).

What's the reason for that?

like image 715
Philipp Wacker Avatar asked Mar 28 '26 07:03

Philipp Wacker


1 Answers

From the MDN documentation regarding a p element:

The start tag is required. The end tag may be omitted if the <p> element is immediately followed by an <address>, <article>, <aside>, <blockquote>, <div>, <dl>, <fieldset>, <footer>, <form>, <h1>, <h2>, <h3>, <h4>, <h5>, <h6>, <header>, <hr>, <menu>, <nav>, <ol>, <pre>, <section>, <table>, <ul> or another <p> element, or if there is no more content in the parent element and the parent element is not an element. (link)

The use of the <ol> tag immediately after/inside the <p> tag closes the <p>. In your case, this means the <p> tag has no content. Take a look at the snippet below, I have the two ols in a p and alternatively in a div then I select the parents with plain javascript and log their inner html:

var p = document.getElementsByTagName("p")[0]

console.log("p:", p.innerHTML);

var div = document.getElementsByTagName("div")[0]

console.log("div:", div.innerHTML);
<p> 
    <ol id="First list">
        <li>foo</li>
        <li>bar</li>
    </ol>
    <ol id="Second list">
        <li>baz</li>
    </ol>
</p>

<div>
    <ol id="First list">
        <li>foo</li>
        <li>bar</li>
    </ol>
    <ol id="Second list">
        <li>baz</li>
    </ol>
</div>



<script src="https://d3js.org/d3.v4.min.js"></script>

So, if you place the ols in a div, you should be able to get this to work:

<div>
    <ol id="First list">
        <li>foo</li>
        <li>bar</li>
    </ol>
    <ol id="Second list">
        <li>baz</li>
    </ol>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
    sel = d3.select("div").selectAll("ol")

    console.log("number of elements in selection: ", sel.size())
</script>
like image 197
Andrew Reid Avatar answered Mar 30 '26 02:03

Andrew Reid