简体   繁体   中英

Simple D3.js text selection

I've run into a strange scenario using D3 to create a simple form-like experience.

The flow goes something like this...

1) Create the element using D3, with a default value

2) Bind a function to a button to read the value of this text area and do stuff

var content = d3.select('#content');
            content.append('div')
                    .append("input")
                    .attr("type", "text")
                    .attr("id", "textinput")
                    .attr("size", "40")
                    .attr("value","Default Text");

            content.append('div')
                    .html('Get contents...')
                    .on("click", function () {
                        console.log("D3 Selection: " + d3.select("#textinput").attr('value'));
                        console.log("DOM Selection: " + document.getElementById("textinput").value);
                    });

The value of the DOM selection is whatever has been entered by the user, and the value of the D3 selection is always "Default Text", no matter what the user has entered:

D3 Selection: Default Text
DOM Selection: I typed something

What am I missing (aside from the obvious knowledge, skill etc. - in my defense I mostly just do this for fun)? Is the D3 selector not supposed to function in this way?

Dave

Instead of using .attr(), you should use .property() instead.

according to: https://github.com/d3/d3-3.x-api-reference/blob/master/Selections.md#property

Some HTML elements have special properties that are not addressable using standard attributes or styles. For example, form text fields have a value string property, and checkboxes have a checked boolean property. You can use the property operator to get or set these properties, or any other addressable field on the underlying element, such as className .

The reason why you can set the value via the .attr() method, but not get it, is because .attr() interacts with the underlying HTML. User interaction doesn't affect the HTML, so those changes aren't reflected when you get via .attr().

Edit: Updated the link to the d3v3 API. The same also holds true for d3v4, though the description is slightly different: https://github.com/d3/d3-selection/blob/master/README.md#selection_property

You would get the same "Default Text" from DOM if you called:

document.getElementById("textinput").getAttribute("value")

You can get the input value from a d3 selction accessing node() first:

d3.select("#textinput").node().value 

使用.property('value')而不是.attr('value')

When you do

.attr("id", "textinput")
.attr("size", "40")
.attr("value","Default Text");

You are giving the #textinput element a value=Default text ie:

<div id="textinput" value="Default Text"></div>

So you are not making its innerHTML Default Text but you are giving it an attribute like a class. And in the console you are asking for that value with your d3 selection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM