Метод Jquery не работает с динамически генерируемыми элементами

#javascript #html #jquery

#javascript #HTML #jquery

Вопрос:

Я пытаюсь создать прайс-лист и проверить его значения.

Это моя функция:

 (function($) {
        $.fn.inputFilter = function(inputFilter) {
            return this.on("input keydown keyup mousedown mouseup select contextmenu drop", function() {
                if (inputFilter(this.value)) {
                    this.oldValue = this.value;
                    this.oldSelectionStart = this.selectionStart;
                    this.oldSelectionEnd = this.selectionEnd;
                } else if (this.hasOwnProperty("oldValue")) {
                    this.value = this.oldValue;
                    this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
                } else {
                    this.value = "";
                }
            });
        };
    }(jQuery));


    // Para números enteros
    $(".intTextBox").inputFilter(function(value) {
        return /^-?d*$/.test(value);
    });  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="intTextBox" id="intTextBox">  

Это работает нормально.

Но когда я вставляю элементы динамически, метод не работает.

 (function($) {
        $.fn.inputFilter = function(inputFilter) {
            return this.on("input keydown keyup mousedown mouseup select contextmenu drop", function() {
                if (inputFilter(this.value)) {
                    this.oldValue = this.value;
                    this.oldSelectionStart = this.selectionStart;
                    this.oldSelectionEnd = this.selectionEnd;
                } else if (this.hasOwnProperty("oldValue")) {
                    this.value = this.oldValue;
                    this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
                } else {
                    this.value = "";
                }
            });
        };
    }(jQuery));


    // Para números enteros
    $(".intTextBox").inputFilter(function(value) {
        return /^-?d*$/.test(value);
    });
    
    $('#add').click(function(e){
      $('#generate').append('<input id="intTextBox" class="intTextBox">');
    }
    );  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="add">ADD</button>
<div id="generate">
  <input id="intTextBox" class="intTextBox">
</div>  

как я мог это решить? Я искал все утро, спасибо за чтение.(У меня есть больше методов проверки, это небольшое резюме).

Комментарии:

1. Вам нужно будет повторно применить входной фильтр после добавления нового элемента. Кроме того, вам действительно не следует создавать несколько элементов на одной странице с одинаковым идентификатором.

2. Вы называете имя человека. Их нет в комнате. Ничего не происходит. Они входят в комнату. Вы ожидаете, что этот человек будет знать, что он был вызван. Этого не происходит! Вы должны инициализировать его после добавления элемента на страницу.

3. спасибо за ваш ответ, как я могу это сделать?

4. Вы ссылаетесь на новый элемент и вызываете для него метод…

Ответ №1:

добавьте элементы DOM с уже подключенными методами проверки

     $('#add').click(function(e){
      $('#generate').append('<input id="intTextBox" 
        class="intTextBox">').inputFilter(function(value) {
         return /^-?d*$/.test(value);
        });
      }
    );
  

Комментарии:

1. Не сработает, вы прикрепляете его к элементу generate, а не к входным данным

Ответ №2:

Приведенный ниже код рандомизирует ваш идентификатор для нового элемента, чтобы избежать конфликта (не идеальное решение; просто халтурный обходной путь для примера), а затем применяет фильтр к новому элементу.

 (function($) {
  $.fn.inputFilter = function(inputFilter) {
    return this.on("input keydown keyup mousedown mouseup select contextmenu drop", function() {
      if (inputFilter(this.value)) {
        this.oldValue = this.value;
        this.oldSelectionStart = this.selectionStart;
        this.oldSelectionEnd = this.selectionEnd;
      } else if (this.hasOwnProperty("oldValue")) {
        this.value = this.oldValue;
        this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
      } else {
        this.value = "";
      }
    });
  };
}(jQuery));

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

// Para números enteros
$(".intTextBox").inputFilter(function(value) {
  return /^-?d*$/.test(value);
});

$('#add').click(function(e) {
  let randomId = "intTextBox_"   getRandomInt(100000);
  $('#generate').append(`<input id="${randomId}" class="intTextBox">`);
  $(`#${randomId}`).inputFilter(function(value) {
    return /^-?d*$/.test(value);
  });

});  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="add">ADD</button>
<div id="generate">
  <input id="intTextBox" class="intTextBox">
</div>  

Комментарии:

1. Ваш код все еще может создавать два одинаковых случайных числа. 😉

2. Конечно. Я не подразумевал, что это постоянное решение проблемы с идентификатором; просто чтобы избежать конфликта для примера. Но при первом нажатии есть 1 шанс из 100000, что идентификатор не будет уникальным :). Я обновил ответ, чтобы указать, что это обходной путь для примера, а не окончательное решение этой конкретной проблемы.

Ответ №3:

Когда вы ссылаетесь на элемент, он не продолжает искать новые элементы, которые добавляются после выполнения кода. Поэтому он не будет находить динамически созданные входные данные.

Вам нужно создать элемент и использовать InputFilter для этого элемента.

 $(".intTextBox").inputFilter(function(value) {
    return /^-?d*$/.test(value);
});

$('#add').click(function(e){
  var newInput = $('<input name="intTextBox" class="intTextBox">');
  newInput.inputFilter(function(value) {
    return /^-?d*$/.test(value);
  });
  $('#generate').append(newInput);
}
  

чтобы удалить дублирование кода

 function addFilter (elems) {
  elems.inputFilter(function(value) {
    return /^-?d*$/.test(value);
  });
}

addFilter($(".intTextBox"));

$('#add').click(function(e){
  var newInput = $('<input name="intTextBox" class="intTextBox">');
  addFilter(newInput);
  $('#generate').append(newInput);
}
  

Комментарии:

1. Спасибо за ваш ответ, он работает для меня. Если бы я мог отдать вам голоса «за», я бы отдал их.

2. Поэтому отметьте его как ответ @JhonMaldonado, если он работает для вас.