为什么D3仅在第一次关注输入工作?

时间:2017-06-06 19:14:23

标签: javascript d3.js focus html-form

focus on an input field使用D3是可能的,甚至不需要to go through setTimeout(我不知道为什么,但我不抱怨)。

但这只是第一次有效。第二次按Set(即:SetResetSet)后,输入字段无法获得焦点。为什么呢?

将回调设置为焦点after the transition is complete会给我一个错误。

<!DOCTYPE HTML>
<head>
    <style>
        div { width: 300px; }
        div#outerdiv  { height: 500px; background-color: #ccc; }
        div#topdiv    { height: 400px; background-color: #dff; }
        div#bottomdiv { height: 0px;   background-color: #ffd; display: 'none' }
        input:focus { background-color: pink; }
    </style>
</head>
<body>
    <div id="outerdiv">
        <div id="topdiv">
            <button onclick=open_form();>Set</button>
            <button onclick=close_form();>Reset</button>
        </div>

        <div id="bottomdiv">
            <form action="javascript:close_form()">
                Name:
                <input type="text" id="myTextField" name="name">
                <input type="submit" name="submit" value="Submit">
            </form>
        </div>
    </div>

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

    <script>
        function open_form() {
            d3.select('#topdiv').transition().duration(500)
              .style('height', '100px');
            d3.select('#bottomdiv').transition().duration(500)
              .style('height', '300px').style('display', 'inline-block');

            d3.select("#myTextField").node().focus();
        } 
        function close_form() {
            d3.select('#topdiv').transition().duration(500)
              .style('height', '390px');
            d3.select('#bottomdiv').transition().duration(500)
              .style('height', '10px').style('display', 'none');
        }
    </script>
</body>

2 个答案:

答案 0 :(得分:1)

无法找到#myTextField,因为它处于转型中期。您可以通过删除display:inline-block的转换来解决此问题,如下所示。

function open_form() {
    d3.select('#topdiv').transition().duration(500)
      .style('height', '100px');
    d3.select('#bottomdiv').style('display', 'inline-block');
    d3.select('#bottomdiv').transition().duration(500)
      .style('height', '300px');
    d3.select("#myTextField").node().focus();
} 

答案 1 :(得分:1)

每次按重置按钮,即调用close_form()时,您的#bottomdiv都会转换为display: none

d3.select('#bottomdiv').transition().duration(500)
    .style('height', '10px').style('display', 'none');

但这有一些副作用。查看focus management上的HTML5规范显示,一个未呈现的元素也不可聚焦:

  

7.4.2重点管理

     

如果满足以下所有条件,则元素可以聚焦:

     

因此,下次你点击 Set 来调用open_form()时,输入无法调焦,因为转换到inline-block尚未结束。解决此问题的最简单方法是listen转换结束后发生的end事件。

   d3.select('#bottomdiv').transition().duration(500)
       .style('height', '300px').style('display', 'inline-block')
       .on("end", () => d3.select("#myTextField").node().focus());

请查看以下代码片段以了解正常工作:

&#13;
&#13;
function open_form() {
    d3.select('#topdiv').transition().duration(500)
      .style('height', '100px');
    d3.select('#bottomdiv').transition().duration(500)
      .style('height', '300px').style('display', 'inline-block')
      .on("end", () => d3.select("#myTextField").node().focus());

} 
function close_form() {
    d3.select('#topdiv').transition().duration(500)
      .style('height', '390px');
    d3.select('#bottomdiv').transition().duration(500)
      .style('height', '10px').style('display', 'none');
}
&#13;
div { width: 300px; }
div#outerdiv  { height: 500px; background-color: #ccc; }
div#topdiv    { height: 400px; background-color: #dff; }
div#bottomdiv { height: 0px;   background-color: #ffd; display: 'none' }
input:focus { background-color: pink; }
&#13;
<body>
    <div id="outerdiv">
        <div id="topdiv">
            <button onclick=open_form();>Set</button>
            <button onclick=close_form();>Reset</button>
        </div>

        <div id="bottomdiv">
            <form action="javascript:close_form()">
                Name:
                <input type="text" id="myTextField" name="name">
                <input type="submit" name="submit" value="Submit">
            </form>
        </div>
    </div>

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

</body>
&#13;
&#13;
&#13;