Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 18.06.2011, 14:36
Профессор
Отправить личное сообщение для Маэстро Посмотреть профиль Найти все сообщения от Маэстро
 
Регистрация: 02.07.2010
Сообщений: 642

Как стереть содержимое поля INPUT по клавише Esc? bug FireFox?
Вроде бы простая задача:
пользователь ввёл что-либо в поле ввода input, потом передумал и отменяет ввод нажатием клавиши Esc (стирает введенный в поле текст).
Оказалось, что FireFox с этим не согласен.
Вот простой проверочный код:
<html>
<body>
<script type="text/javascript">

var o=document.createElement('INPUT');

o.onkeydown = function(event) 
{
event = event || window.event;
var k = event.keyCode;
if (k == 27) this.value = '';
};

document.body.appendChild(o);
</script>
</body>
</html>
Кто-нибудь может объяснить происходящее?
Это баг FireFox или фича? Или я что-то не так делаю?
Firefox 4.0.1
Ответить с цитированием
  #2 (permalink)  
Старый 18.06.2011, 17:31
Аватар для Amphiluke
   ☽
Отправить личное сообщение для Amphiluke Посмотреть профиль Найти все сообщения от Amphiluke
 
Регистрация: 07.01.2011
Сообщений: 254

В чем причина, хз, но методом проб можно придумать массу решений…
Например, использовать событие keyup вместо keydown, или выполнять очистку поля про помощи таймера с задержкой 0.
if (k == 27)
    setTimeout((function(inp) {return function() {inp.value = '';}})(this), 0);

Или как-то дополнительно воздействовать на элемент, чтобы он «зашевелился»
if (k == 27) {this.blur(); this.value=""; this.focus();}
Ответить с цитированием
  #3 (permalink)  
Старый 20.06.2011, 12:08
Профессор
Отправить личное сообщение для Маэстро Посмотреть профиль Найти все сообщения от Маэстро
 
Регистрация: 02.07.2010
Сообщений: 642

Сообщение от Amphiluke Посмотреть сообщение
В чем причина, хз, но методом проб можно придумать массу решений…
Например, использовать событие keyup вместо keydown
-По onkeyup не работает в Opera (аналогично как в FireFox по onkeydown).

Сообщение от Amphiluke Посмотреть сообщение
или выполнять очистку поля про помощи таймера с задержкой 0.
if (k == 27)  setTimeout((function(inp) {return function() {inp.value = '';}})(this), 0);
-В FireFox это не работает.

Сообщение от Amphiluke Посмотреть сообщение
Или как-то дополнительно воздействовать на элемент, чтобы он «зашевелился»
if (k == 27) {this.blur(); this.value=""; this.focus();}
-Да, это в FireFox работает!
Кстати, в Opera по this.focus() курсор обратно не ставится.
В принципе, манипуляция фокусом в простейшем случае решает проблему с FireFox, но... здесь я привел упрощенный фрагмент кода. В программе же у меня на onblur повешена целая ветка алгоритма с цепочкой функций. И дергать ее таким методом не хотелось бы.

Я нашел ещё один способ побороть проблему с FireFox для своего частного случая. У меня по нажатию клавиши Esc содержимое инпута не только стирается, но еще и весь инпут полностью прячется! Инициализация инпута (его "всплытие"/открытие) производится по первому нажатому пользователем символу. При этом я сначала очищаю поле this.value='' (и FireFox реально его стирает!) и сразу же в поле передается нажатый символ.

По ходу обнаружил в FireFox 4.0.1 бооольшую утечку памяти! Оставил компьютер включенным на субботу/воскресенье и в понедельник увидел, что он съел памяти более 1 Гигабайта!!! Вот уж не люблю выход новых релизов. Всегда не знаешь чего от них ожидать. Кстати я писал аналогичное об Опере здесь Сумасшедшая утечка памяти в Opera при использовании javascript в IFRAME
Но это уже другая тема.

А Вам спасибо за участие в теме.
Ответить с цитированием
  #4 (permalink)  
Старый 20.06.2011, 14:00
Профессор
Отправить личное сообщение для nikita.mmf Посмотреть профиль Найти все сообщения от nikita.mmf
 
Регистрация: 01.02.2010
Сообщений: 364

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title></title>
</head>
<body>
	<script type="text/javascript">
		var inputElem = document.createElement('input');
		inputElem[window.opera ? "onkeypress" : "onkeyup"] = function(event) {
			event = event || window.event;
			var k = event.keyCode;
			if ( k == 27 ) { 
				event.preventDefault();
				this.value = ''
			};
		};
		document.body.appendChild( inputElem );
</script>
</body>
</html>
Ответить с цитированием
  #5 (permalink)  
Старый 20.06.2011, 15:55
Профессор
Отправить личное сообщение для Маэстро Посмотреть профиль Найти все сообщения от Маэстро
 
Регистрация: 02.07.2010
Сообщений: 642

nikita.mmf,
сначала отрицательное:
1. Ваш код в IE вызывает ошибку. Лично я использую кроссбраузерный эквивалент погашения события cancelEvent() вместо preventDefault):
function cancelEvent(e) 
// кроссбраузерная функция подавления события
{ 
e = e ? e : window.event; 
if (e.stopPropagation) e.stopPropagation(); 
else if (e.preventDefault) e.preventDefault();  
e.cancelBubble=true;e.cancel=true;e.returnValue=false;return false; 
};

2. Стараюсь максимально не использовать onkeyup. Почему? Хотите смейтесь, хотите нет, но сейчас расскажу. Когда твой продукт рассчитан на несколько тысяч пользователей, то всегда найдется с десяток раздраженных людей, которым не нравится то то, то сё. И их мнение приходится учитывать. Есть пользователи, которые жмут кнопку и... держат её в нажатом состоянии... и ждут пока что-то произойдет! а т.к. сработка происходит по keyup, то они не понимают, что происходит, потому что ничего не происходит. Вот так вот.

из положительного:
1. Ваш код по onkeyup в FireFox работает.

2. Я увидел в Вашем коде интересную (вроде бы несущественную) деталь: использование preventDefault() до inp.value=''; а не после inp.value=''; как это делал я. Что это меняет? Оказывается, приятная неожиданность: в Opera при этом не слетает курсор с поля. Спасибо.
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разным элементам input - разное форматирование. Как? eclipse (X)HTML/CSS 1 25.10.2007 13:55