'Autofocus' 属性对输入元素只起作用一次,但不会起作用两次

'Autofocus' attribute works once, but not twice, on input elements

我在 d3.js 中编码,有时使用 input 元素来收集用户的输入而不使用 form。这很好用。

但我注意到我无法在动态页面上始终如一地应用 autofocus 属性;它仅在第一次应用时有效。

下面是一个示例,包含所有编码。注意 autofocusinput 元素第一次出现时是如何完美工作的。第二次就不行了,虽然编码是一样的

解决这个问题会改善智能手机上的用户体验。

注意: .focus() 方法不起作用,我认为那是因为它只能应用于属于 input 的元素一个表格。

h1,
p,
input {
  font-family: sans-serif;
}

h1 {
  font-size: 1rem;
}

input {
  padding: 0.5rem;
  border-radius: 1rem;
  color: gray;
  opacity: 0;
}

input::placeholder {
  font-weight: normal;
  color: silver;
}

input:focus {
  outline: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>

<div id="container">
  <h1>Testing the autofocus</h1>
</div>

<script>
  // wait 2 seconds, then create input element with autofocus
  d3.timeout(function() {
    createFirstInput();
  }, 2000);

  function createFirstInput() {
    d3.select("h1")
      .text("Creating first input field")
    d3.select("#container")
      .append("input")
      .attr("type", "text")
      .attr("placeholder", "input goes here")
      .attr("autofocus", "autofocus")
      .transition()
      .duration(2000)
      .style("opacity", 1);
    d3.select("#container")
      .append("p")
      .text("autofocus works; cursor appears in input field");
    // delete input field after 5 seconds
    d3.timeout(function() {
      d3.select("h1")
        .text("Creating second input field");
      d3.selectAll("input, p")
        .remove();
      // create second input field
      createSecondInput();
    }, 5000);
  }

  function createSecondInput() {
    // wait 2 seconds, then create input element with autofocus
    d3.timeout(function() {
      d3.select("#container")
        .append("input")
        .attr("type", "text")
        .attr("placeholder", "input goes here")
        .attr("autofocus", "autofocus")
        .transition()
        .duration(2000)
        .style("opacity", 1);
      d3.select("#container")
        .append("p")
        .text("autofocus doesn't work; no cursor in input field");
    }, 2000);
  }
</script>

focus() 方法确实有效:

input.node().focus();

此处,input 是附加输入的 D3 选择(顺便说一下,为您的选择命名!这是一个很好的做法)。通过在该选择上使用 node() 我们得到实际的 DOM 元素,我们使用 focus() 方法。

这是演示:

h1,
p,
input {
  font-family: sans-serif;
}

h1 {
  font-size: 1rem;
}

input {
  padding: 0.5rem;
  border-radius: 1rem;
  color: gray;
  opacity: 0;
}

input::placeholder {
  font-weight: normal;
  color: silver;
}

input:focus {
  outline: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>

<div id="container">
  <h1>Testing the autofocus</h1>
</div>

<script>
  // wait 2 seconds, then create input element with autofocus
  d3.timeout(function() {
    createFirstInput();
  }, 2000);

  function createFirstInput() {
    d3.select("h1")
      .text("Creating first input field")
    d3.select("#container")
      .append("input")
      .attr("type", "text")
      .attr("placeholder", "input goes here")
      .attr("autofocus", "autofocus")
      .transition()
      .duration(2000)
      .style("opacity", 1);
    d3.select("#container")
      .append("p")
      .text("autofocus works; cursor appears in input field");
    // delete input field after 5 seconds
    d3.timeout(function() {
      d3.select("h1")
        .text("Creating second input field");
      d3.selectAll("input, p")
        .remove();
      // create second input field
      createSecondInput();
    }, 5000);
  }

  function createSecondInput() {
    // wait 2 seconds, then create input element with autofocus
    d3.timeout(function() {
      var input = d3.select("#container")
        .append("input")
        .attr("type", "text")
        .attr("placeholder", "input goes here")
        .attr("autofocus", "autofocus")
        .transition()
        .duration(2000)
        .style("opacity", 1);
      input.node().focus();
      d3.select("#container")
        .append("p")
        .text("autofocus with focus() method does work");
    }, 2000);
  }
</script>

这是因为自动对焦应该只给一个输入元素。如果要更改焦点,请使用 node() 的 focus() 方法 这是代码。

<div id="container">
  <h1>Testing the autofocus</h1>
</div>

<script>
  // wait 2 seconds, then create input element with autofocus
  d3.timeout(function() {
    createFirstInput();
  }, 2000);

  function createFirstInput() {
    d3.select("h1")
      .text("Creating first input field")
    d3.select("#container")
      .append("input")
      .attr("type", "text")
      .attr("placeholder", "input goes here")
      .transition()
      .duration(2000)
      .style("opacity", 1)
      .node()
      .focus();
    d3.select("#container")
      .append("p")
      .text("autofocus works; cursor appears in input field");
    // delete input field after 5 seconds
    d3.timeout(function() {
      d3.select("h1")
        .text("Creating second input field");
      d3.selectAll("input, p")
        .remove();
      // create second input field
      createSecondInput();
    }, 5000);
  }

  function createSecondInput() {
    // wait 2 seconds, then create input element with autofocus
    d3.timeout(function() {
      var input = d3.select("#container")
        .append("input")
        .attr("type", "text")
        .attr("placeholder", "input goes here")
        .transition()
        .duration(2000)
        .style("opacity", 1)
        .node()
        .focus();
      d3.select("#container")
        .append("p")
        .text("autofocus should be given to only one input element. If you want to change the focus use focus() method of node()");
    }, 2000);
  }
</script>