Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   "Залипание" onkeydown() (https://javascript.ru/forum/events/10656-zalipanie-onkeydown.html)

MazenRat 14.07.2010 09:19

"Залипание" onkeydown()
 
Недавно столкнулся с проблемой: мне всего-то нужно было сделать обработчик на прижатую клавишу клавиатуры. Немного подумав, сделал для этого обработку события onkeydown(). Все было замечательно, пока я не подержал в нажатом состоянии клавишу с привязанным к ней обработчиком некоторое время... и каково же было мое удивление, когда функция-обработчик стала вызываться снова, снова и снова... :blink: Сначала подумал, что это виновата новая Opera, но после проверки других браузеров понял, что однократно onkeydown() срабатывает только в старой Opera 9.62 и Iceweasel 3.0.6. Во всех остальных (FireFox 3.6.6, Google Chrome 5.0, Safari 5.0, IE 8) обработчик почему-то "залипает" :(

Может, кто-нибудь объяснит нубу, как сделать, чтобы функция-обработчик вызывалась однократно?

Вот мой код на jQuery: ( Кликните по фрейму и попробуйте нажать и держать клавишу [t], и увидите, как будет непрерывно меняться содержимое div с id = "test" )

<!-- Подключаем библиотеку jQuery: -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type='text/javascript'>
$( document ).ready(
    function(){
        $( document ).keydown(
            function( e ){
                  if( e.keyCode  == 84 )
                      // Если была прижата клавиша "t":
                      $( "#test" ).html( Math.random() );
            }
        );
    }
);
</script>
<div id = "test"></div>

Kolyaj 14.07.2010 11:57

Если только отслеживать ещё и keyup. Один раз обработчик вызвали, пока не будет keyup, больше его не вызываем.

MazenRat 14.07.2010 21:18

Цитата:

Сообщение от Kolyaj (Сообщение 63660)
Если только отслеживать ещё и keyup. Один раз обработчик вызвали, пока не будет keyup, больше его не вызываем.

Да, я сам уже пробовал такой способ. :) Вот только проверил его лишь в Opera 10.60, а в остальных браузерах посмотреть поленился, когда получил в этой букве O отрицательный результат. А зря.

Вообщем, этот код работает во всех браузерах, перечисленных мной в первом посте, исключая новую Opera:

<!-- Подключаем библиотеку jQuery: -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type='text/javascript'>
$( document ).ready(
    function(){
        // Переменная-флажок: true - keyup() сработал,
        // false - еще нет:
        *!*var flag = true;*/!*

        $( document ).keydown(
            function( e ){
                if( e.keyCode == 84 *!*&& flag*/!* ){
                    // Если была прижата клавиша "t":
                    $( "#test" ).html( 'keydown сработал! ' + Math.random() );
                    *!*flag = false;*/!*
                }
            }
        );
        $( document ).keyup(
            function( e ){
                if( e.keyCode == 84 ){
                    // Если была отжата клавиша "t":
                    $( "#test2" ).html( 'keyup сработал! ' + Math.random() );
                    *!*flag = true;*/!*
                }
            }
        );
    }
);
</script>
<div id = "test" style = "color: red"></div>
<div id = "test2" style = "color: blue"></div>


Моя Opera 10.60 (под linux) в этом примере делает "залипание" как для события onkeydown(), так и для onkeyup(), что делает использование переменной flag бессмысленным. Но почему это происходит? И можно ли как-нибудь решить эту проблему? :)

Gozar 14.07.2010 22:32

а у меня работает в Opera 10.60 (под linux) нормально, точно также как и в FF

MazenRat 15.07.2010 06:59

Цитата:

Сообщение от Gozar (Сообщение 63803)
а у меня работает в Opera 10.60 (под linux) нормально, точно также как и в FF

Во дела :blink: Сейчас обновил Opera с 9.62 до 10.60 в винде XP под VirtualBox - все работает как по маслу... Выходит, это только для Debian новая Opera такая ущербная?


Часовой пояс GMT +3, время: 03:01.