简体   繁体   中英

JavaScript Click EventListener works only once

I have a number input and I want to show inputs based on the chosen number. The problem is the click event works only once.

Here is the HTML code :

<div class="an-panel m-t-30 row" id="an-inputs-panel">
  <div class="col-md-12">
    <h4 class="text-center">Inputs</h4>
  </div>
  <div class="col-md-12 p-t-20">
    <div class="col-md-3 col-md-offset-4">
      <input type="number" id="inputs_number" min="2" max="5" value="2" class="form-control" placeholder="">
    </div>
    <div class="col-md-4">
      <a id="btn_add_input">Add</a>
    </div>
  </div>
</div>

The JavaScript code takes the number input's value and loop through it to create new inputs:

window.onload = function() {
  // Add inputs
  var btn_input = document.getElementById('btn_add_input'),
    inputs_panel = document.getElementById('an-inputs-panel'),
    inputs_number = document.getElementById('inputs_number');

  btn_input.addEventListener("click", function() {
    alert(inputs_number.value);
    inputs_panel.innerHTML += createInputs(inputs_number.value);
  });

  function createInputs(length) {
    var inputs = "";
    for (var i = 0; i < length; i++) {
      inputs += `
        <div id="an-panel-container">
          <div class="col-md-12">
            <u><h5 class="text-center p-t-20">Input ` + (i + 1) + `</h5></u>
          </div>
          <div class="col-md-12 p-t-20">
            <div class="col-md-4 col-md-offset-2">
              <label>Field name</label>
              <input type="text" class="form-control">
            </div>
            <div class="col-md-4">
              <label>Input type</label>
              <select class="form-control">
                <option>text</option>
                <option>email</option>
                <option>phone</option>
                <option value="">number</option>
                <option value="">textarea</option>
              </select>
            </div>
          </div>
        </div>`;
    }
    return inputs;
  }
}

It happens because you remove the elements that has events bound by using .innerHTML . You need to bind the events once more after replacing the elements.

So the code should look like this: (but there is a little mistake. Events binds multiple times to elements that haven't removed)

window.onload = function() {
  // Add inputs
  var btn_input = document.getElementById('btn_add_input'),
    inputs_panel = document.getElementById('an-inputs-panel'),
    inputs_number = document.getElementById('inputs_number');

  bindEvents();

  function bindEvents() {
    btn_input.addEventListener("click", function() {
      alert(inputs_number.value);
      inputs_panel.innerHTML += createInputs(inputs_number.value);
      bindEvents();
    });
  }

  function createInputs(length) {
    var inputs = "";
    for (var i = 0; i < length; i++) {
      inputs += `
        <div id="an-panel-container">
            <div class="col-md-12">
                <u><h5 class="text-center p-t-20">Input ` + (i + 1) + `</h5></u>
            </div>
            <div class="col-md-12 p-t-20">
                <div class="col-md-4 col-md-offset-2">
                    <label>Field name</label>
                    <input type="text" class="form-control">
                </div>
                <div class="col-md-4">
                    <label>Input type</label>
                    <select class="form-control">
                        <option>text</option>
                        <option>email</option>
                        <option>phone</option>
                        <option value="">number</option>
                        <option value="">textarea</option>
                    </select>
                </div>
            </div>
        </div>`;
    }
    return inputs;
  }
}

Well, based on @Lain's comment, it seems that innerHTML loses the handlers when it gets reparsed, so I changed:

inputs_panel.innerHTML += createInputs(inputs_number.value);

To:

inputs_panel.insertAdjacentHTML('beforeend', createInputs(inputs_number.value));

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