为啥 D3 对输入的关注只在第一次起作用?
Posted
技术标签:
【中文标题】为啥 D3 对输入的关注只在第一次起作用?【英文标题】:Why does D3's focus on an input work only the first time?为什么 D3 对输入的关注只在第一次起作用? 【发布时间】:2017-11-07 22:43:56 【问题描述】:使用 D3 可以focus on an input field,甚至不需要to go through setTimeout
(我不知道为什么,但我没有抱怨)。
但这只适用于第一次。第二次按下Set
(即:Set
、Reset
、Set
)后,输入字段没有获得焦点。为什么?
将回调设置为焦点 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>
【问题讨论】:
【参考方案1】:每次你点击重置按钮,即当close_form()
被调用时,你的#bottomdiv
被转换为display: none
:
d3.select('#bottomdiv').transition().duration(500)
.style('height', '10px').style('display', 'none');
不过,这有一些副作用。查看focus management 上的 HTML5 规范显示,未呈现的元素也不可聚焦:
7.4.2 焦点管理
如果满足以下所有条件,则元素是可聚焦的:
[…] 元素是being rendered 或[…]。
因此,下次您点击 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());
查看下面的 sn-p 以获取工作演示:
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');
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;
<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>
【讨论】:
家庭作业:找出此处列出的 .on('end', ..) 和 .each('end', ..) 之间的区别:***.com/questions/10692100/… @Sebastian 好吧,transition.each("end")
是在 v3 中注册处理函数的方式。从 v4 开始,它被重命名为 transition.on("end")
。【参考方案2】:
它无法找到#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();
【讨论】:
以上是关于为啥 D3 对输入的关注只在第一次起作用?的主要内容,如果未能解决你的问题,请参考以下文章