Выбрав объект с помощью jQuery после функции изменения, изменил html-структуру элемента, который нужно было выбрать

0

У меня есть следующий код (игра с некоторыми выборами).

После первой функции изменения вторая функция изменения не работает:

        jQuery('.toPopSelect').change(function(){
            console.log("hey");
        });  

Я думаю, потому что первая функция изменения заменяет некоторые html, а jQuery не может последовать класс.toPopSelect.

Любая идея, почему это происходит? есть ли способ вокруг него?

    <select class="theSelect">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
    </select>

    <div class="toPopulate">
        <select class="toPopSelect">
            <option value="1">1</option>
            <option value="2">2</option>
        </select>
    </div>




jQuery(document).ready(function(){

        jQuery('.theSelect').change(function(){
            jQtoPopulate = jQuery('.toPopulate');
            jQtoPopulate.empty();
            jQtoPopSelect = jQuery('.toPopSelect');
            v = jQuery(this).val();

            if ( v == 1) {
                console.log("ues")
                jQtoPopulate.html('<input type="text" size="60"><\/input>');
            } else {
                jQtoPopulate.html('<select class="toPopSelect"><option value="1">1<\/option><option value="2">2<\/option><option value="3">3<\/option><option value="4">4<\/option><option value="5">5<\/option><\/select>');

                jQtoPopSelect.append('<option value="6">6<\/option>');
            }

        });

        jQuery('.toPopSelect').change(function(){
            console.log("hey");
        });

    });

Есть идеи?

Теги:

4 ответа

0
Лучший ответ

Как вы говорите. Поскольку вы меняете DOM, когда вы меняете первый элемент select, он записывает второй элемент select и, следовательно, элемент, к которому относится ваш console.log("hey"); обработчик события больше не существует.

Когда ваш код работает следующим образом:

jQuery('.toPopSelect').change(function(){
            console.log("hey");
});

то, что он делает, привязывает обработчик ко всем элементам, которые соответствуют .toPopSelect во время выполнения кода. Он не привязывает обработчик событий ко всем и каждому .toPopSelect который будет когда-либо возникать на вашей странице.

Поэтому после изменения DOM вы можете повторно привязать обработчик событий:

jQuery('.theSelect').change(function(){
    // stuff that changes DOM here

    jQuery('.toPopSelect').change(function(){
        console.log("hey");
    });
});

Другое, что вы можете сделать, это использовать:

$('.toPopulate').on('change', '.toPopSelect', function(){
    console.log("hey");
});

Это присваивает обработчик события .toPopulate но будет инициироваться только событиями, соответствующими второму аргументу (.toPopSelect). См.: http://api.jquery.com/on/

Обратите внимание, что если вы измените или удалите. .toPopulate из DOM, это также больше не будет применяться. (В основном выберите ближайшего предка .toPopSelect, который останется в DOM.)

  • 0
    Отличное объяснение, но не будет ли присоединение происходить каждый раз, когда происходит первое событие изменения? Я верю, что решение Кришны будет более эффективным. Вы не согласны?
  • 0
    да, я включил оба решения, чтобы охватить все основы. Что касается того, что является более эффективным, это зависит от множества факторов, но во многих случаях я думаю, что о разнице не стоит беспокоиться. Лично я бы однажды прикрепил событие к .toPopulate , тогда вам не нужно об этом сильно беспокоиться.
Показать ещё 1 комментарий
2

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

JsFiddle, чтобы проиллюстрировать это: http://jsfiddle.net/s6MVQ/

$(document).on('change', '.toPopSelect', function(){
    alert("ok");
});

Дополнительная информация: http://api.jquery.com/on/

  • 0
    заменить S на $
  • 0
    Ты за ответ получаю ошибку - ReferenceError: изменение не определено
Показать ещё 4 комментария
1

Вы должны правильно выполнить делегирование событий. Поскольку .toPopSelect создается динамически, вы должны обрабатывать событие следующим образом. Документация jquery.on()

$(document).on('change', '.toPopSelect', function(){
    console.log("hey");
}); 

Еще лучше (для производительности), если вы можете заменить document статическим внешним классом контейнера /id

  • 0
    Я чувствовал, что BYossarian более полный, поэтому я выбрал его ответ в качестве принятого. Я проголосовал за ваш ответ
  • 0
    @DanyD - ура .. не проблема.
0

попробуй это:

jQuery(document).ready(function(){

        jQuery('.theSelect').change(function(){
            jQtoPopulate = jQuery('.toPopulate');
            jQtoPopulate.empty();
            jQtoPopSelect = jQuery('.toPopSelect');
            v = jQuery(this).val();

            if ( v == 1) {
                console.log("ues")
                jQtoPopulate.html('<input type="text" size="60"><\/input>');
            } else {
                jQtoPopulate.html('<select class="toPopSelect"><option value="1">1<\/option><option value="2">2<\/option><option value="3">3<\/option><option value="4">4<\/option><option value="5">5<\/option><\/select>');

                jQtoPopSelect.append('<option value="6">6<\/option>');
            }

        });

        var c = $(document);
        c.delegate(".toPopSelect","change",function(){ alert("hey"); });

    });

Ещё вопросы

Сообщество Overcoder
Наверх
Меню