событие onkeyup JavaScript

Вот мой код:

function search_buddy() 
{
    $.post("num.php",function (ret){
        num=ret;
    });
    $("#Layer7").html(num);
}
</script>

<div id="Layer8">
     Find a buddy : 
    <input type="text" id="search" onkeyup="search_buddy()"/>&nbsp;:
</div>

Теперь, когда я ввожу один символ в текстовое поле с id=search, кажется, что функция search_buddy не срабатывает. Принимая во внимание, что если я ввожу два символа или более, функция работает отлично. Почему это происходит?


person Anant    schedule 08.10.2010    source источник
comment
не могли бы вы предоставить тестовую страницу для проверки всего кода?   -  person    schedule 08.10.2010
comment
кажется, работает для меня jsfiddle.net/sMZ2j (слегка измененный пример)   -  person scunliffe    schedule 08.10.2010


Ответы (1)


Лучший ресурс о событиях DOM: http://www.quirksmode.org/dom/events/keys.html

Похоже, ваш обработчик событий «search_buddy» запускает запрос AJAX, который является асинхронным. Остальная часть функции выполняется параллельно с запросом AJAX, поэтому "num" не определен до возврата $.post.

// num is undefined here... unless your network has 0 latency
$("#Layer7").html(num);

Вам нужно обернуть этот код (вставленный выше) в функцию обратного вызова. Похоже, это параметр номер 3: http://api.jquery.com/jQuery.post/

Непроверено, но лучше всего предположить:

function search_buddy() {
    $.post("num.php", function (ret) {
        num=ret;
        $("#Layer7").html(num);
    });
}

Вот некоторые модификации, которые помогут вам понять:

function search_buddy() {
    alert("before the $.post execution");
    $.post("num.php", function (ret) {
        num=ret;
        $("#Layer7").html(num);
        alert("$.post callback");
    });
    alert("immediately after the $.post execution");
}

Примечание: «оповещение» остановит всю обработку JavaScript, чтобы вы могли видеть, когда происходят события.

person Oxyrubber    schedule 08.10.2010
comment
я прочитал здесь webcheatsheet.com/javascript/variables.php, что глобальные переменные не нужны объявление var, и, следовательно, я намеревался объявить num глобально. И почему код нормально работает с двумя и более символами? - person Anant; 08.10.2010
comment
Ваша переменная неявно глобальна, потому что вы явно не определили ее с помощью var. Это означает, что ваш обработчик событий выполняется для первого события... вы просто не видите никакого вывода, потому что вы меняете HTML до того, как получите ответ ASYNC. Использование моего кода должно включать изменения HTML в код ответа. - person Oxyrubber; 08.10.2010
comment
^^ Извините, я не понимаю. Как изменяется HTML перед ответом? Код $(#Layer7).html(num); после функции $.post() не так ли? - person Anant; 08.10.2010
comment
Операция $.post происходит вне этого потока JavaScript. Думайте об этом как о разветвленной операции. Это асинхронность в асинхронном JavaScript и XML (AJAX). - person Oxyrubber; 08.10.2010
comment
Честно говоря, я думаю, что страница quirksmode, на которую вы ссылаетесь, является довольно плохим ресурсом для ключевых событий. Он неполный и не объясняет различные цели нажатия/нажатия клавиши по сравнению с нажатием клавиши. В частности, он не объясняет в черно-белых тонах, что только keypress можно использовать для дополнительной информации о символе, введенном пользователем, что является фактом, о котором большинство разработчиков, похоже, не подозревают. Намного лучше unixpapa.com/js/key.html. - person Tim Down; 08.10.2010
comment
@ user465089: извините, сэр, я не понимаю, что вы имеете в виду под операцией $.post, которая происходит за пределами этого потока JavaScript. - person Anant; 08.10.2010
comment
@Tim Down: Пожалуйста, продолжайте тему - person Oxyrubber; 08.10.2010
comment
@Anant: функция $.post обрабатывается параллельно со всем остальным прилегающим к ней Javascript. $.post (1) отправляет сообщение HTTP на сервер, (2) ждет ответа сервера, (3) получает ответ и (4) запускает функцию обратного вызова (ту, которую я написал для вас). В вашем коде $(#Layer7).html(num); работает в то же время (1) происходит. Если вы переместите этот код в функцию обратного вызова, вы можете быть уверены, что это произойдет во время (4) - person Oxyrubber; 08.10.2010
comment
хм, я начинаю тебя понимать. Одно общее сомнение: как $(#Layer7).html(num); после $.post(), разве он не выполняется после $.post()? - person Anant; 08.10.2010
comment
В общем, да. Разница в том, что $.post внутренне отправляет xmlhttprequest, а затем продолжает обработку остальной части JavaScript после вызова $.post. Когда ответ возвращается, ваша функция обратного вызова выполняется вскоре после этого. Это похоже на то, что происходит с setTimeout (я обновлю свой исходный ответ примером). - person Oxyrubber; 08.10.2010
comment
@user465089: Почему мой комментарий не по теме? Если бы я опубликовал это как ответ, это было бы не по теме, но как комментарий к утверждению в вашем ответе, что я с ним не согласен, было совершенно справедливо. - person Tim Down; 08.10.2010
comment
@Tim: Ваш ресурс напрямую не помог решить проблему. Мы должны отключить это, если вы хотите обсудить больше. - person Oxyrubber; 08.10.2010