When cloning an input, only one of the inputs works with an "oninput" function, while the other does not

huangapple go评论65阅读模式
英文:

When cloning an input, only one of the inputs works with an "oninput" function, while the other does not

问题

我有一个包含一些li元素的ol元素。每个li中还有一个带有oninput函数的输入。当单击li时,它会被克隆并添加到单独的列中。克隆工作正常,除了输入元素。只有一个输入元素在被克隆后似乎能够读取任何值(我假设是原始输入元素)。

任何帮助将不胜感激。

<!-- 这是一个示例的JavaScript代码片段 -->
<!-- 这是 JavaScript 代码部分 -->

let exerciseBuilder = document.getElementById("exercise-builder");
let exerciseList = document.getElementById("list-of-exercises");
let repsLabel = document.querySelectorAll(".reps-label");
let ETA = document.getElementById("ETA");
// $(".reps").hide();
$(repsLabel).hide();

// 这是克隆和复制li元素的函数。我认为问题可能在这里。
function addToBuilder(e) {
  let target = e.target;
  if (target.matches('li')) {
    exerciseBuilder.insertBefore(e.target, exerciseBuilder.firstChild);
    let clone = e.target.cloneNode(true)
    exerciseList.appendChild(clone)
    $(e.target.children).show();
  }
}

// 这个函数只是从右列中移除li元素。这似乎可以正常工作。
function removeFromBuilder(e) {
  let target = e.target;
  if (target.matches('li')) {
    e.target.remove();
  }
}

// 这是我在HTML中链接的oninput函数的一部分。
function estimatedTimeOfCompletion() {
  let repsValue = document.getElementById("back-squat-reps").value;
  console.log(repsValue);
}

exerciseList.addEventListener("click", function(e) {
  addToBuilder(e);
})

exerciseBuilder.addEventListener("click", function(e) {
  removeFromBuilder(e);
}
<!-- 这是 HTML 代码部分 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- 这是左列的开始,输入元素似乎可以正常工作。 -->
<div id="list-of-exercises-container">
  <ol id="list-of-exercises">
    <li class="exercise" id="back-squat">Back Squat
      <!-- 目前我只在一个输入元素上进行了测试,但计划将其应用到所有输入元素。 -->
      <input class="reps" type="text" id="back-squat-reps" oninput="estimatedTimeOfCompletion()"><label class="reps-label">Reps</label>
    </li>
    <li class="exercise" id="power-clean">Power Clean
      <input class="reps"><label class="reps-label">Reps</label>
    </li>
    <li class="exercise" id="bench-press">Bench Press
      <input class="reps"><label class="reps-label">Reps</label>
    </li>
    <li class="exercise" id="box-jump">Box Jump
      <input class="reps"><label class="reps-label">Reps</label>
    </li>
  </ol>
</div>
<!-- 这是右列的开始。当li被克隆到这里时,输入元素停止工作。 -->
<div id="exercise-builder">
  <ul>
  </ul>
  <p id="ETA">Estimated Time Of Completion: </p>
</div>
英文:

I have an ol element with some li's. Inside each li is also an input with an oninput function. When the li is clicked on, it's cloned and added to a separate column. The cloning works fine, except for the inputs. Only one of the inputs seems to actually read any values once it's cloned (I assume it's the original).

Any help would be greatly appreciated.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let exerciseBuilder = document.getElementById(&quot;exercise-builder&quot;);
let exerciseList = document.getElementById(&quot;list-of-exercises&quot;);
let repsLabel = document.querySelectorAll(&quot;.reps-label&quot;);
let ETA = document.getElementById(&quot;ETA&quot;);
// $(&quot;.reps&quot;).hide();
$(repsLabel).hide();

// This is the function that clones and copies over the li Element. I assume the problem is somewhere in here. 
function addToBuilder(e) {
  let target = e.target;
  if (target.matches(&#39;li&#39;)) {
    exerciseBuilder.insertBefore(e.target, exerciseBuilder.firstChild);
    let clone = e.target.cloneNode(true)
    exerciseList.appendChild(clone)
    $(e.target.children).show();
  }
}

// This is the function simply removes the li Element from the right column. This seems to work OK.
function removeFromBuilder(e) {
  let target = e.target;
  if (target.matches(&#39;li&#39;)) {
    e.target.remove();
  }
}

// This is the oninput function that I have linked in the HTML of the very first input.
function estimatedTimeOfCompletion() {
  let repsValue = document.getElementById(&quot;back-squat-reps&quot;).value;
  console.log(repsValue);
}

exerciseList.addEventListener(&quot;click&quot;, function(e) {
  addToBuilder(e);
})

exerciseBuilder.addEventListener(&quot;click&quot;, function(e) {
  removeFromBuilder(e);
})

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;!-- Here is the start of the left column, where the input seems to work correctly. --&gt;
&lt;div id=&quot;list-of-exercises-container&quot;&gt;
  &lt;ol id=&quot;list-of-exercises&quot;&gt;
    &lt;li class=&quot;exercise&quot; id=&quot;back-squat&quot;&gt;Back Squat
      &lt;!-- I have have the oninput function on one of the inputs at the moment for testing purposes, but the plan is to put on all. --&gt;
      &lt;input class=&quot;reps&quot; type=&quot;text&quot; id=&quot;back-squat-reps&quot; oninput=&quot;estimatedTimeOfCompletion()&quot;&gt;&lt;label class=&quot;reps-label&quot;&gt;Reps&lt;/label&gt;
    &lt;/li&gt;
    &lt;li class=&quot;exercise&quot; id=&quot;power-clean&quot;&gt;Power Clean
      &lt;input class=&quot;reps&quot;&gt;&lt;label class=&quot;reps-label&quot;&gt;Reps&lt;/label&gt;
    &lt;/li&gt;

    &lt;li class=&quot;exercise&quot; id=&quot;bench-press&quot;&gt;Bench Press
      &lt;input class=&quot;reps&quot;&gt;&lt;label class=&quot;reps-label&quot;&gt;Reps&lt;/label&gt;
    &lt;/li&gt;
    &lt;li class=&quot;exercise&quot; id=&quot;box-jump&quot;&gt;Box Jump
      &lt;input class=&quot;reps&quot;&gt;&lt;label class=&quot;reps-label&quot;&gt;Reps&lt;/label&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
&lt;!-- Here is the start of the right column. When the li is cloned over here, the input stops working. --&gt;
&lt;div id=&quot;exercise-builder&quot;&gt;
  &lt;ul&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;ETA&quot;&gt;Estimated Time Of Completion: &lt;/p&gt;
&lt;/div&gt;

<!-- end snippet -->

答案1

得分: 1

这是根据MDN文档的设计。 cloneNode() 不会复制事件处理程序。

您需要为每个创建的元素添加事件监听器。

let clone = e.target.cloneNode(true)
clone.addEventListener("click", <function>);
exerciseList.appendChild(clone)
英文:

This is by design per the MDN documentation. cloneNode() does not copy event handlers.

You'll have to add the event listener to each element created.

        let clone = e.target.cloneNode(true)
        clone.addEventListener(&quot;click&quot;, &lt;function&gt;);
        exerciseList.appendChild(clone)

答案2

得分: 0

你可以将事件对象传递给输入事件处理程序,并使用 e.target.value 读取当前 <input> 的值(或者,你可以使用 this 将元素本身传递给函数)。然而,你应该考虑使用 addEventListener 而不是内联事件处理程序。

<input class="reps" type="text" oninput="estimatedTimeOfCompletion(event)">
function estimatedTimeOfCompletion(e) {
  let repsValue = e.target.value;
  console.log(repsValue);
}

最好给 <input> 添加一个特定的类,并使用事件委托。请注意,克隆带有id属性的元素会导致文档中存在重复的id。

英文:

You can pass the event object to the input event handler and read the value of the current &lt;input&gt; with e.target.value (alternatively, you could pass the element itself to the function with this). However, you should consider using addEventListener instead of inline event handlers.

&lt;input class=&quot;reps&quot; type=&quot;text&quot; oninput=&quot;estimatedTimeOfCompletion(event)&quot;&gt;
function estimatedTimeOfCompletion(e) {
  let repsValue = e.target.value;
  console.log(repsValue);
}

It would be better to give the &lt;input&gt; a specific class and use event delegation. Note that cloning an element with the id attribute causes there to be duplicate ids in the document.

huangapple
  • 本文由 发表于 2023年2月9日 00:51:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75389095.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定