Событие 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()})