Javascript-форум (https://javascript.ru/forum/)
-   Opera, Safari и др. (https://javascript.ru/forum/css-html-browser/)
-   -   Opera, событие не возникает вновь при вдавленной кнопке. (https://javascript.ru/forum/css-html-browser/27561-opera-sobytie-ne-voznikaet-vnov-pri-vdavlennojj-knopke.html)

micscr 17.04.2012 10:35

Opera, событие не возникает вновь при вдавленной кнопке.
 
код
jQuery(document).ready(function(){
  jQuery(document).keydown(function(ev){
     if ((ev.keyCode > 36) && (ev.keyCode < 41)) {
	 nazata(ev.keyCode);	//действия 								 
     }
  });			  
});

Когда стрелку вдавливаешь, то событие должно повторяться. Так и работает во всех моих браузерах кроме оперы. Что делать?

devote 17.04.2012 11:43

Цитата:

Сообщение от micscr
Когда стрелку вдавливаешь, то событие должно повторяться.

используйте keypress, я вообще удивлен что другие браузеры обрабатывают событие keydown так же как событие keypress

micscr 17.04.2012 12:18

хм перетащил проверку стрелок на keypress , в опере стало окей.
Но в хроме стрелки не работают на keypress(это у меня записано, поэтому я их на keydown и проверял)

Kolyaj 17.04.2012 12:30

С клавишами в браузерах всё плохо, по ним можно диссертацию писать. Причём с разными клавишами по разному плохо. Если говорить про стрелки, то при их залипании
* В IE и в Chrome повторяется keydown
* В Опере повторяется keypress
* В Firefox-е повторяются и keydown, и keypress.

Вот и делай что хочешь. Получается надо оба ловить, но при этом в Firefrox-е одно из них игнорировать.

По логике, правильное поведение здесь у IE и у Chrome. Firefox решил перестраховаться, но в целом тоже покатит. А Опера в своём репертуаре мудацкого браузера.

devote 17.04.2012 12:51

Цитата:

Сообщение от Kolyaj
А Опера в своём репертуаре мудацкого браузера.

не согласен, keypress и в африке keypress. Это событие должно повторяться в тех случаях когда клавишу зажмешь и продолжаешь держать ее. Тогда при нажатии срабатывает keydown а повторы уже идут на keypress... Так что этот мудатский браузер как вы говорите, делает таки наоборот правильнее всех иных браузеров. Повторять keydown при зажатой клавише, вот это мудатство.

devote 17.04.2012 13:00

не просто так события называются так как называются:
keydown - нажали клавишу, то-есть опустили, срабатывает событие что именно нажали клавишу
keypress - от английского слова pressed (зажата) то-есть клавиша зажата, соответственно все повторы идут на это событие до тех пор пока клавиша не будет отжата.
keyup - подняли клавишу, то-есть отпустили.

Вся эта логика работает во всех языках в которых я программировал, а их более десяти как минимум. Поэтому Опера все же работает правильнее всех.

Octane 17.04.2012 13:04

А вот кстати еще удивляет по какой такой логике сделали разный порядок срабатывания:
mousedown → mouseup → click
и
keydown → keypress → keyup

----------
Помня что click последним возникает, сначала хотел написать, что логичнее было бы повторять keydown, а Opera как всегда, но потом посмотрел, как ведут себя браузеры…

devote 17.04.2012 13:15

Цитата:

Сообщение от Octane
А вот кстати еще удивляет по какой такой логике сделали разный порядок срабатывания:

А попробуй их пойми, разработчики Оперы не выдумывали никакой логики, а сделали так как принято в языке Си. Именно по порядку keydown → keypress → keyup, насчет разрабов других браузеров я сам бы хотел понять по какой такой логике решили повторять keydown при зажатой клавише.

Kolyaj 17.04.2012 13:18

devote,
это всего лишь ваши фантазии. keypress должен срабатывать, когда введён какой-то символ, а не когда нажата клавиша. Поэтому нажатие стрелок не должно вызывать keypress вовсе, т.к. никакой символ при этом не вводится. Другими словами, keypress работает с символами, которые могут отличаться на одной и той же клавише в зависимости от раскладки или от shift/caps.
http://learn.javascript.ru/keyboard-events

keydown/keyup же работают с самими клавишами, независимо от раскладки.

Kolyaj 17.04.2012 13:20

Цитата:

Сообщение от Octane
mousedown → mouseup → click

Событие click по-определению срабатывает в случае, если и mousedown, mouseup случились на одном DOM элементе. Т.е. для проверки, нужно ли сгенерировать click, нужно сначала поймать mouseup, поэтому click будет всегда после.

devote 17.04.2012 13:25

Цитата:

Сообщение от Kolyaj
это всего лишь ваши фантазии. keypress должен срабатывать, когда введён какой-то символ, а не когда нажата клавиша.

То-есть по вашему я всю жизнь программирую и событие на всех языках под названием keypress оказывается везде совсем не keypress а как тоесть это правильнее тогда по вашему нужно было назвать keycharinput тогда уж. KeyPress и в африке keypress про буквы в названии события не слова нет, а значит ввод тут совершенно не причем. И к вашему сведению стрелки тоже делаю ввод данных в бувер клавиатуры, просто программы их обрабатывают так как им надо. И не надо ляля. Keypress четко своим названием говорит что именно press а не input

Kolyaj 17.04.2012 13:33

Можно, конечно, встать в позу, и кричать, что всю жизнь на Си пишу, и там вот так. А можно пойти и почитать, как оно не в Си, а в JavaScript.
Ещё раз цитата из ссылки выше
Цитата:

Возникает сразу после keydown, если нажата символьная клавиша, т.е. нажатие приводит к появлению символа.
Нажатие на стрелки к появлению символа не приводит.

devote 17.04.2012 13:41

мне эта цитата ни о чем не говорит, ибо я больше доверяю спецификациям.. Хотя и в них не всегда все найдешь. А то что в JS принято так как вы говорите, то это принято кем? Простыми JS программистами? А где оф. документ об этом говорящий? Нету? Ну еще бы, проще же для себя сделать выводы самому. А может вовсе вывод сделан от принятых решений в браузере допотопных времен. Я лишь знаю одно, что мои привычным требованиям в программировании, опера меня вполне устраивает, потому что я получаю то что ожидаю. А не то что где-то кто-то решил что в JS оно будет так. Флаг им в руки.

devote 17.04.2012 13:47

Хотя да вы правы, в JS оно так, и спецификацию нашел: http://dev.w3.org/2006/webapi/DOM-Le...-type-keypress но странно конечно что они решили сделать в JS именно так.

devote 17.04.2012 13:52

НО! Есть приписка в той же спецификации:
Цитата:

⚠Warning! the keypress event type is defined in this specification for reference and completeness, but this specification deprecates the use of this event type. When in editing contexts, authors can subscribe to the "input" event defined in [HTML5] instead.
Говорящая о том что данное поведение в последующем может измениться, так как в спецификации HTML5 появилось событие oninput которое и нужно использовать для отлова вводимых клавиш. Поэтому Опера вполне норм работает с этим событием, так же и событие oninput в Опере тоже есть, которое и ловит ввод данных.

Так что я уверен что в будущем полюбившееся вам поведение измениться у события keypress

micscr 17.04.2012 15:57

спс за ответы, пока я подумал не усложнять мой код чисто из-за оперы, т.к. для своего сайта скрипт.

micscr 19.04.2012 16:15

переделал все таки еще и под оперу, глянул что в рунете это оч. популярный браузер. Даже не знаю почему.
Может кому пригодится, кроссбраузерная обработка стрелок и пробела:
var agt = navigator.userAgent.toLowerCase();
var is_opera = ((agt.indexOf("opera") != -1)||(window.opera));
jQuery(document).ready(function(){
  jQuery(document).keypress(function(ev){
     if (ev.which == 32)  {
       nazata(32);	
       return false;
     }  
     if (is_opera) {
       if ((ev.keyCode > 36) && (ev.keyCode < 41)) {
		   nazata(ev.keyCode);	 								 
		   return false;
	   }     
     }
	 
  });			
  jQuery(document).keydown(function(ev){ 
     if (is_opera) return false;
     if ((ev.keyCode > 36) && (ev.keyCode < 41)) {
		 nazata(ev.keyCode);	 								 
		 return false;
	 }
  });	
});

devote 19.04.2012 17:15

Цитата:

Сообщение от micscr
var is_opera = ((agt.indexOf("opera") != -1)||(window.opera));

не лучший вариант юзать юзерагент...

раз уж пошла такая пьянка вот мой вариант:
<!DOCTYPE html>
<html>
	<head>
		<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
		<script type="text/javascript">

			var keypressed = false, count = 0;

			function _log( str ) {
				document.body.innerHTML = "(" + count++ + ") " + str + ( keypressed ? ", вы продолжаете ee держать!" : "" );
			}

			$(document).bind( "keydown keypress", function( e ) {

				var keystring = {
					"37": "стрелка влево",
					"38": "стрелка вверх",
					"39": "стрелка вправо",
					"40": "стрелка вниз"
				}

				var timeStamp = (new Date().getTime());

				if ( !document.timeStamp || ( ( document.timeStamp + 10 ) < timeStamp ) ) {
					if ( e.which === 32 ) {
						_log( "Нажат пробел" );
					} else if ( e.keyCode > 36 && e.keyCode < 41 ) {
						_log( "Нажата функциональная клавиша: " + ( keystring[ e.keyCode ] || "код клавиши " + e.keyCode ) );
					} else {
						_log( "Нажата клавиша: " + ( keystring[ e.keyCode ] || "код клавиши " + e.keyCode ) );
					}
					document.timeStamp = timeStamp;
				}

				keypressed = true;

				return false;

			}).keyup(function(){

				count = 0;
				keypressed = false;

				_log( "Отпустили клавиши" );
			});
		</script>
	</head>
	<body>
	</body>
</html>


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