jquery выбирает динамический идентификатор класса внутри динамически созданного div

У меня есть JS, который динамически создает новый div (входы внутри формы). Работает отлично. У меня отдельно есть jquery, который проверяет ввод раскрывающегося списка и показывает отдельный div, если щелкнуть конкретный выбор. Работает отлично.

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

JSFiddle: http://jsfiddle.net/Xyzeg/ (измените раскрывающийся список "CPI" в первом поле , чтобы событие началось). Сценарий включает другой JS для динамического создания div.

Любые указатели будут оценены.

<div style="float:left">
<div id='dynamicInput'>Pension 1: Amount: $<input type='text' name='adjustmentInputs[]' value='0' size='13' maxlength='20'>Start Year:
<input type='text' name='adjustmentInputs[]' value='2032' size='5' maxlength='6'>
<input type='hidden' name='adjustmentInputs[]' value='2100'>
<select name='adjustmentInputs[]'>
  <option value='InflationAdjusted'>Inflation Adjusted</option>
  <option value='NotInflationAdjusted'>Not Inflation Adjusted</option>
</select>by
<select name='adjustmentInputs[]' class='pensionAdjustment1'>
  <option value='CPI'>CPI</option>
  <option value='constantPercentage'>Constant %</option>
</select>
<div id='constantPercentageText1' style='display: none'>@ <input type='text' name='adjustmentInputs[]' value='3' size='5' maxlength='6'>%</div>
</div>
   <input type="button" value="Add another Portfolio Adjustment" onClick="addInput('dynamicInput');">
</div>
<script>
$("[class*=pensionAdjustment]").change(function() {
    var n = $(this).attr('class').replace('pensionAdjustment', '');
    var newId = "constantPercentageText" + n;
    var selectedItem = $(this).children('option:selected');
    if ($(this).val() == 'constantPercentage') {
        $("#constantPercentageText" + n).css('display', 'inline');
        $("#constantPercentageText" + n).show();
    } else {
        $("#constantPercentageText" + n).css('display', 'none');
    }
});  
</script>

person bo_knows    schedule 16.07.2013    source источник
comment
Вы должны делегировать события элементу, который существует на момент привязки событий.   -  person Mathletics    schedule 16.07.2013
comment
Чтобы расширить комментарий @Mathletics, посетите jQuery.on. $(document).on('change', "[class*=pensionAdjustment]", function() {...   -  person dinjas    schedule 16.07.2013
comment
Итак, вы говорите, что, поскольку динамически созданные div не существуют до того, как произойдет поиск, я не могу привязать события, как я? Какое тогда решение?   -  person bo_knows    schedule 16.07.2013


Ответы (3)


Вам нужно делегировать вновь созданные элементы!

Измените эту строку

$("[class*=pensionAdjustment]").change(function() {

to

$(document).on('change',"[class*=pensionAdjustment]",  function() {
person Zevi Sternlicht    schedule 16.07.2013
comment
Я пока не могу принять ответ (слишком рано, слишком новый пользователь), но это помогло. Вы можете немного объяснить, что здесь происходит? Так что я действительно могу понять разницу. - person bo_knows; 16.07.2013
comment
@bo_knows круто, нет проблем, это одна из тех вещей, к которой нужно привыкнуть в jQuery, она решит множество ошибок новичков! - person Zevi Sternlicht; 16.07.2013
comment
часть $ (document) .on назначает делегирование для будущего создаваемого контента? - person bo_knows; 16.07.2013
comment
Вместо того, чтобы выбирать элементы, которые были там во время загрузки, мы ищем реальные живые элементы! - person Zevi Sternlicht; 16.07.2013
comment
аааа. Значит, все, что не загружено (что-то изменилось), нужно использовать on ()? Я ценю объяснение - person bo_knows; 16.07.2013
comment
да. Это помогает потому, что объект document находился поблизости во время загрузки. Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. - person Zevi Sternlicht; 16.07.2013
comment
Превосходно. Теперь мне просто нужно избавиться от моего старого JS, который динамически добавляет div, и я буду хорош со всеми jquery. Хорошие времена. Но на данный момент это не мое внимание. Ваше здоровье! - person bo_knows; 16.07.2013
comment
@bo_knows, зачем от него избавляться, просто убедитесь, что используете делегаты, on() вместо прямых обработчиков событий - person Zevi Sternlicht; 16.07.2013

Вы можете использовать

$(document).on('change', '[class*=pensionAdjustment]', function(){
    // your code
});

Было бы лучше, если бы вы использовали родительский div вместо document.

Обновление: элементы, которые вы динамически внедряете в DOM, не присутствовали, когда событие было зарегистрировано, поэтому новые элементы не запускают событие. С помощью event delegation (регистрация event в родительском элементе) эту проблему можно решить, потому что, когда какой-либо элемент запускает событие, событие всплывает до последнего элемента (вверх), который он может найти, и таким образом родительский элемент запускается, но позади сцена, происходит что-то вроде следующего

e = e || window.event;
var el = e.target || e.srcElement;

Вы можете проверить это .

person The Alpha    schedule 16.07.2013
comment
@InGodITrust, Да, я ответил на ваш комментарий, и это было seems similar enouth tho :-). - person The Alpha; 16.07.2013
comment
@InGodITrust, а теперь нет :-) - person The Alpha; 16.07.2013
comment
@InGodITrust, Ха-ха, но он на правильной платформе, и я думаю, что скоро он узнает об этом, потому что я думаю, что это больше место для обучения, чем набор представителей, все эксперты здесь ответят, не так ли? - person The Alpha; 16.07.2013
comment
Конечно, здесь есть пользователи со 100 тысячами репутации, которые были новичками, когда пришли. Вы услышите лучшие ответы на проблемы и станете лучшим программистом! Приятного вечера! - person Zevi Sternlicht; 16.07.2013
comment
@InGodITrust, ты тоже :-) - person The Alpha; 16.07.2013

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

$(document).on('change', "[class*=pensionAdjustment]", function(){
    var n = $(this).attr('class').replace('pensionAdjustment', '');
    var newId = "constantPercentageText" + n;
    var selectedItem = $(this).children('option:selected');
    if ($(this).val() == 'constantPercentage') {
        $("#constantPercentageText" + n).css('display', 'inline');
        $("#constantPercentageText" + n).show();
    } else {
        $("#constantPercentageText" + n).css('display', 'none');
    }
});
person Jonny Sooter    schedule 16.07.2013