Кнопка jQuery .toggle() переключает только все остальные элементы.

Мой код генерирует разные элементы нажатием одной кнопки. Один из сгенерированных элементов - это кнопки, которые я хочу включать и выключать сгенерированные части текста. Функция jQuery .toggle() работает для первого сгенерированного элемента. Затем он работает только для последнего сгенерированного элемента и всех остальных до этого (скажем, с 5 сгенерированных элементов, он будет работать на 5, 3, 1, но не на 2 и 4). Я думаю, что проблема с классом, я думаю, потому что я могу из веб-консоли в Firefox использовать команду.toggle (), чтобы удалить ее вручную. Я думаю, это будет означать, что кнопка не срабатывает. Я в растерянности.

Вот jsFiddle, показывающий поведение http://jsfiddle.net/JaLBR/1/ Вот код:

recursionCounter = 0
$(document).ready(function(){

$("#compute").click(function(){

    //add the toggle data
    $("#buttons").append("<input type=button value=\"Toggle\" class=\"removeBtn\" id=\"recursion" + recursionCounter + "\">")
    //add the recursion counter to the div element
    $("#recursion" + recursionCounter).data("recurs", recursionCounter)

    //make a new section for toggling purposed
    $("#results").append("<o" + (recursionCounter) + ">")
    //This code write the results to screen
    $("o" + (recursionCounter)).append("<br><br> <b>Recursion " + (recursionCounter) + "</b>")
    $("o" + (recursionCounter)).append("<br> Symmetric")

//toggles the recursion info
$(".removeBtn").on("click", function() {
    var count = $(this).data("recurs")
    $("o" + count).toggle()   
})


recursionCounter = recursionCounter + 1
})

})

С соответствующими на html, как видно на скрипке.

Я думаю, что это может быть связано с вложением вызова клика внутри другого клика? Я попытался убрать его из щелчка "вычислить", но тогда он вообще не переключался (возможно, из-за области действия). Но проблема проявляется только при переключении. Если сделать.toggle () в.hide(), все кнопки работают. Если я делаю отдельные кнопки показать / скрыть, то это работает нормально. Если я напишу оператор if..else, который выполняет переключающее поведение (используя.is(:visible)), он также не работает.

2 ответа

Решение

jQuery не заменяет обработчики событий. Если вы прикрепите два обработчика событий:

$('#foo').click(function() {
    console.log('a');
});

$('#foo').click(function() {
    console.log('a');
});

И нажмите на #foo, оба они будут стрелять.

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

Чтобы исправить это, удалите этот обработчик событий из вашего .click() обратный вызов и просто присоедините его с делегированием события:

$('#buttons').on("click", ".removeBtn", function () {
    var count = $(this).data("recurs");
    $("o" + count).toggle()
});

Делегирование события присоединяет обработчик события к #buttons, который затем делегирует событие элементу, по которому щелкнули. Это будет учитывать все элементы, которые соответствуют вашему селектору, даже если они будут добавлены позже.

Демо: http://jsfiddle.net/JaLBR/4/

Вам нужно поставить .removeBtn событие клика за пределами #compute событие нажатия кнопки:

recursionCounter = 0
$(document).ready(function () {
    $("#compute").click(function () {

        $("#buttons").append("<input type=button value=\"Toggle\" class=\"removeBtn\" id=\"recursion" + recursionCounter + "\">")
        $("#recursion" + recursionCounter).data("recurs", recursionCounter)

        $("#results").append("<o" + (recursionCounter) + ">")
        //This code write the results to screen
        $("o" + (recursionCounter)).append("<br><br> <b>Recursion " + (recursionCounter) + "</b>")
        //the removeButton
        //$("o" + (recursionCounter)).append("<input type=button value=\"Remove\" class=\"removeBtn\" id=\"remove" + recursionCounter + "\">")

        $("o" + (recursionCounter)).append("<br> Symmetric")
        recursionCounter = recursionCounter + 1
    });

    //removes the recursion info
    $('#buttons').on('click', ".removeBtn", function () {
        var count = $(this).data("recurs")
        console.log(count)
        $("o" + count).toggle()
    });
});

FIDDLE DEMO

Другие вопросы по тегам