Событие jQuery.change() запускается только один раз

У меня есть приложение, которое извлекает имена проектов из базы данных, когда DOM готов. Каждый проект добавляется к <select><option> в html <form>. После заполнения списка пользователь может выбрать заголовок проекта, который будет запрашивать оставшуюся информацию из базы данных, относящейся к этому проекту.

Для этого я использую метод $.change() jQuery. К сожалению, событие запускается только один раз, когда элемент <select> создается и добавляется в DOM. Выбор другого проекта из списка не запускает событие и поэтому не вызывает вызов $.post().

$(function(){
    getProjects();
    var firstLoad = true;

    $("select").change(retrieveProject); // Removed parenthesis based on answers

    // On page load, get project names from the database and add them to a Select form element
    function getProjects() {
        var selectionList;
        $.getJSON("php/getProjects.php", function (data) {
            selectionList = "<form><select>";
            for (var i = 0; i < data.length; i++) {
                selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>";
            }
            selectionList += "</select></form>";
        }).complete(function() {
           $('#project-selection-menu').append(selectionList).removeClass('hidden');
           firstLoad = false;
        });
    }

    function retrieveProject() {
        if ( firstLoad == true ){
            alert(firstLoad); // This alert fires
            return false;
        } else {
            alert(firstLoad); // This alert doesn't fire
            $.post("php/getProjects.php", function (data) { // This should have been "php/retrieveProject.php"!
                // Do stuff with the returned data
            }).complete(function() {
               console.log("Success.");
            });
        }
    }
)};

Ответ 1

Неправильно настроите обработчик событий:

$("select").change(retrieveProject);

В вашем коде вы были вызывают функцию "retrieveProject", а возвращаемое значение этого вызова функции передавалось как обработчик "change" (и, конечно, не имеет никакого эффекта). Поэтому выяснилось, что событие генерировалось при загрузке страницы.

Когда вы работаете с функцией как значением, вы не используете () после ссылки на функцию — это сама ссылка (имя функции, в данном случае), которую вы хотите. Это то, что нужно передать jQuery.

Также — и это важно. убедитесь, что ваш код запущен либо в "готовом", либо в "загрузочном" обработчике, иначе ваш <script> появится после элемента <select> на странице. Если script находится в заголовке документа, он будет работать до анализа DOM, и он не будет иметь никакого эффекта. (Еще один способ справиться с этим - использовать делегированную форму .on(), как предложено в другом ответе.)


Дополнительно: похоже, вы перезаписываете свой элемент <select> при получении содержимого в "getProjects". Таким образом, вы обязательно должны использовать делегированную форму:

$(document).on("change", "select", retrieveProject);

Кроме того, вы должны использовать локальные переменные в "getProjects":

function getProjects() {
    var selectionList; // keep this local to the function - implicit globals are risky

    $.getJSON("php/getProjects.php", function (data) {
        selectionList = "<form><select>";
        for (var i = 0; i < data.length; i++) {
            selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>";
        }
        selectionList += "</select></form>";
    }).complete(function() {
       $('#project-selection-menu').append(selectionList).removeClass('hidden');
       firstLoad = false;
    });
}

Ответ 2

Вам нужно обработать делегирование событий

$(document).on('change', 'select', retrieveProject);

Также удалите () рядом с методом retrieveProject

Ответ 3

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

$("select").change(function(){retrieveProject()});

или

$("select").on('change',function(){retrieveProject()});

Ответ 4

Это то, что вы ищете? Чтобы запустить getProjects после загрузки страницы, просто вызовите ее в своей функции $(document).ready(). Также вам необходимо правильно настроить обработчик change. См. Скрипку для справки.

var firstLoad = true;
getProjects();
$("#selectTest").change(function(){
    retrieveProject();
});

// On page load, get project names from the database and add them to a Select form element
function getProjects() {
    $.getJSON("php/getProjects.php", function (data) {
        selectionList = "<form><select>";
        for (var i = 0; i < data.length; i++) {
            selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>";
        }
        selectionList += "</select></form>";
    }).complete(function() {
       $('#project-selection-menu').append(selectionList).removeClass('hidden');
       firstLoad = false;
    });
}

function retrieveProject() {
    if ( firstLoad == true ){
        alert(firstLoad); // This alert fires
        return false;
    } else {
        alert(firstLoad); // This alert doesn't fire
        $.post("php/getProjects.php", function (data) {
            // Do stuff with the returned data
        }).complete(function() {
           console.log("Success.");
        });
    }
}

http://jsfiddle.net/trevordowdle/Mf38E/

Ответ 5

Попробовать код ниже

$(document).bind('change', 'select', function() {retrieveProject()})