Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   как отделить нажатие символьных клавиш от функциональных? (https://javascript.ru/forum/events/1760-kak-otdelit-nazhatie-simvolnykh-klavish-ot-funkcionalnykh.html)

Kos 24.09.2008 10:59

Ну и что, зато помог очень и времени много потратил.

У тебя, кстати, какая версия ИЕ?

ZoNT 24.09.2008 11:10

у меня есть ИЕ6, ИЕ7, ФФ2, ФФ3, Сафари, Опера 9.5, Хром...

Проверял я в ИЕ7, сейчас посмотрю в ИЕ6...

ZoNT 24.09.2008 11:13

Я тут подумал про ctrl+Z в ИЕ.
Походу ИЕ сбрасывает список изменений, когда перезаписывается value у инпута. А так как я реализовал именно этим способом (так как по другому выходило очень сложно и глючно), то победить можно только преписав всё полностью на другой алгоритм.

Kos 24.09.2008 12:07

А ты знаешь другой способ :eek:

Kos 24.09.2008 12:09

У меня, кстати, первый запрещ. символ в ИЕ 7 вылазит.
Класный наборчик, а у меня тока:
Opera 9.5, FireFox 3, IE7, Chrome

ZoNT 24.09.2008 12:10

другой способ - как я делал с маской:
на кейдаун и кейпресс проверять клавиши и если они подходят, то возвращать true. Тогда value не будет перезаписываться, а будет стандартно средставми браузера просто дописываться в поле (просто не будут допускаться невалидные клавиши). Но в твоём случае возникает слишком много проблем.
Можешь попробовать переделать.

Kos 24.09.2008 12:25

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

ZoNT 24.09.2008 12:36

проблемы в том, что у меня в маске ограниченный набор валидных символов :)
А у тебя - очень большой набор (точки, функциональные клавиши и т.д.). соответственно, чотбы их пропускать во всех бразерах надо писать очень сложные правила проверки...

У меня простые правила проверки, так как мне надо пропускать небольшое кол-во кодов. Остальные обрубаются.
Тебе придётся писать сложные разветвлённые правила на кучу кодов клавиш.

Проверка кодов у меня стоит в функции "P" (ну и делы с бэкспейсами проверяются дополнительно в onkeydown).

Kos 24.09.2008 13:33

Ладно начнем разбиратся по пордку:
во-первых, вся функция setMask вызывается у нас при срабатывании события онкейпресс, но в этой ф-ции ты на это событие вешаешь другую ф-цию. Я ставил алерты, проверял - первый раз он срабатывает из сетмаск, а остальные из той другой ф-ции (вот здесь меня интересует, как такое вообще возмжно и зачем это). Помимо этого есть еще 2а события или не события sC и gS (по моему ты сам их добавил, тогда возникает вопрос: в js к объектам можно добавлять собственные cв-ва и методы?) - они как я понял для сохранения и восстановления пзиции курсора. Но зачем они в маске, если ты говоришь, что в маске ты не переписываешь value. За что отвечает G в функции обработки онкейпресса, и почему в самом начале мы присваеваем ему !c, когда c типа string (здесь мне интересно что может получится от не с, и вообще зачем это, если мы знаем с). Ответь пожалуйста пока на эти вопросы.

ZoNT 24.09.2008 17:09

Цитата:

Сообщение от Kos (Сообщение 6260)
Ладно начнем разбиратся по пордку:
во-первых, вся функция setMask вызывается у нас при срабатывании события онкейпресс, но в этой ф-ции ты на это событие вешаешь другую ф-цию. Я ставил алерты, проверял - первый раз он срабатывает из сетмаск, а остальные из той другой ф-ции (вот здесь меня интересует, как такое вообще возмжно и зачем это). Помимо этого есть еще 2а события или не события sC и gS (по моему ты сам их добавил, тогда возникает вопрос: в js к объектам можно добавлять собственные cв-ва и методы?) - они как я понял для сохранения и восстановления пзиции курсора. Но зачем они в маске, если ты говоришь, что в маске ты не переписываешь value. За что отвечает G в функции обработки онкейпресса, и почему в самом начале мы присваеваем ему !c, когда c типа string (здесь мне интересно что может получится от не с, и вообще зачем это, если мы знаем с). Ответь пожалуйста пока на эти вопросы.

setCursor (sC), getCursor (gC) - это я написал, так как надо ставить курсор в нужную позицию при:
1) удалении выделенного куска
2) пропуске уже присутствующих символов маски (скобки, тире и тд.)
3) при вставке из буфера

К объектам можно добавлять что угодно...

переменная G инициализируется значением !c. Так как в с у нас строка, то её значение будет интерпретироваться как true в логических операциях, соотвтетсвенно !c = false.

Итак, для чего нужно G. В ФФ дэл и бэкспейс передаются и в онкейдаун и в онкейпресс. У других они не передаются в онкейпресс. Чтобы в онкейпрессе второй раз не удалять символы я ставлю в онкейдауне проверку на эти клавиши и проставляю G. Итого при данных клавишах в онкей прессе происходит выход на первой строке.

Kos 03.10.2008 12:08

Наконец-то сумел выбраться в интернет.
По делу:
В твоей ф-ции я так и не разобрался, но зато все-таки сделал нужную ф-цию (помогла твоя идея с G)
В твоей маске у меня в IE7 тоже можно было ввести первый запрещ. символ, но когда я повесил функцию на событие onFocus - все заработало как надо.

Вот привожу код, чего натворил:
datacheck.js:

function DataCheck(I, VList, hint, dX, dY, spX, spY, time) {
	var keydown = false;
	var keyup = true;
	
	r = VList.split('').join('|');
	if (/z/.test(r)) r = r.replace(/z/g,'[a-z]');
	else if (/я/.test(r)) r = r.replace(/я/g,'[а-яё]');
	else if (/a/.test(r)) r = r.replace(/a/g,'[a-zа-яё]');
	else if (/\*/.test(r)) r = r.replace(/\*/g,'[a-zа-яё0-9]');
	r = r.replace(/\(/g,'\\(').replace(/\)/g,'\\)').replace(/\//g,'\\/').replace(/9/g,'\\d').replace(/\./g,'\\.');
	
	var r = new RegExp(r,'i');
	
	function isValid(key) {
		if (VList != '') {
			key = String.fromCharCode(key);
			return r.test(key);
			
		} else return false;
	}
	
	I.onkeydown = function(e, key){
		e = e || event;
		key = e.keyCode || e.charCode;
		
		if (key <= 31 || (key >= 33 && key <= 35) || (key >= 36 && key <=40) || key == 45 || key == 46 || (key >= 112 && key <= 123)) {
			keydown = true;
			if (key != 16) keyup = false;
			
		} else keydown = false;
	}
	
	I.onkeypress = function(e, key) {
		if (keydown) {
			keydown = false;
			return true;
		}
		
		e = e || event;
		key = e.keyCode || e.charCode;
		
		if (e.ctrlKey || e.altKey || !keyup || isValid(key)) return true;
		else {
			showCheckHint();
			return false;
		}
	}
	
	I.onkeyup = function() {
		keyup = true;
	}
	
	I.getCPE = function() {
		if (this.selectionStart) return (this.value.length - this.selectionStart); //Gecko
			else if (document.selection) { //IE
			
			var tr = document.selection.createRange();
			tr.moveEnd('character', this.value.length);
			
			return tr.text.length;
		}
	}
	
	I.setCPE = function(CaretPos) {
		if(this.setSelectionRange) this.setSelectionRange(this.value.length - CaretPos, this.value.length - CaretPos);
		else {
			
			var tr = this.createTextRange();
			tr.collapse(true);
			tr.move('character', this.value.length - CaretPos);
			tr.select();
		}
	}
	
	function myPaste() {
		setTimeout(function() {
			var val_arr = I.value.split('');
			var res_arr = [];
			var change = false;
			
			for(var i = 0; i < val_arr.length; i++)
				if (r.test(val_arr[i]) && VList != '') res_arr.push(val_arr[i]);
				else change = true;
			
			if (change) {
				var pos = I.getCPE();
				I.value = res_arr.join('');
				I.setCPE(pos);
				
				showCheckHint();
			}
		}, 0);
	}
	
	if (!window.opera) I.onpaste = myPaste;
	else I.addEventListener('input', myPaste, false);
	
	function showCheckHint() {
		if (hint) {
			if (dX == undefined) dX = 3;
			if (dY == undefined) dY = 1;
			if (spX == undefined) spX = 5;
			if (spY == undefined) spY = 2;
			if (time == undefined) time = 5000;
			
			if (VList != '') {
				var msg = 'Разрешено вводить только следующие символы: <strong>';
				var vlist_arr = VList.split('');
				
				for (i = 0; i < vlist_arr.length; i++) {
					if (i > 0) msg += ' ';
					
					if (vlist_arr[i] == 'a') msg += 'буквы русского и латинского алфавитов';
					else if (vlist_arr[i] == 'z') msg += 'буквы латинского алфавита';
					else if (vlist_arr[i] == 'я') msg += 'буквы русского алфавита';
					else if (vlist_arr[i] == '9') msg += 'цифры';
					else if (vlist_arr[i] == '*') msg += 'буквы русского и латинского алфавитов цифры';
					else if (vlist_arr[i] == ' ') msg += 'знак пробела';
					else msg += vlist_arr[i];
				}
				
				msg += '</strong>';
				
			} else var msg = 'Запрещено вводить какие либо символы';
			
			ShowHint(I, msg, dX, dY, spX, spY, time);
		}
	}
}


hint.js:

var Hint = document.createElement('div');
Hint.style.display = 'none';
Hint.timer_id = undefined;

Hint.style.fontFamily = 'Arial'; // шрифт подсказки
Hint.style.fontSize = '8pt'; // размер шрифта
Hint.style.color = '#000000'; // цвет шрифта

Hint.style.border = '1px solid #7D8891'; // граница подсказки
Hint.style.backgroundColor = '#FFFFE1'; // фон подсказки
Hint.style.padding = '1px 5px'; // поля подсказки
	
Hint.style.position = 'absolute'; 
Hint.style.zIndex = '100';
	
Hint.style.cursor = 'default';
Hint.onmousedown = function(){ HideHint(); }

function ShowHint(el, msg, dX, dY, spX, spY, time) {
	if (Hint.timer_id) {
		window.clearTimeout(Hint.timer_id);
		Hint.timer_id = undefined;
	}
	
	if (typeof(el) == 'string') el = document.getElementById(I);
	
	Hint.innerHTML = msg;
	Hint.style.top = '-100px';
	Hint.style.left = '-1000px';
	Hint.style.display = 'block';
	
	var w = parseInt(el.offsetWidth); 
	var h = parseInt(el.offsetHeight);
	
	var t = 0; 
	var l = 0; 
	var obj = el; 
	while(obj) { 
		t += parseInt(obj.offsetTop);   
		l += parseInt(obj.offsetLeft); 
		obj = obj.offsetParent;     
	}
	
	switch(dX) {
		case 0:
			Hint.style.left = l - parseInt(Hint.offsetWidth) - spX + 'px';
			break;
		case 1:
			Hint.style.left = l + spX + 'px';
			break;
		case 2:
			Hint.style.left = l + w - parseInt(Hint.offsetWidth) - spX + 'px';
			break;
		case 3:
			Hint.style.left = l + w + spX + 'px';
			break;
	}
	
	switch(dY) {
		case 0:
			Hint.style.top = t - parseInt(Hint.offsetHeight) - spY + 'px';
			break;
		case 1:
			Hint.style.top = t + spY + 'px';
			break;
		case 2:
			Hint.style.top = t + h - parseInt(Hint.offsetHeight) - spY + 'px';
			break;
		case 3:
			Hint.style.top = t + h + spY + 'px';
			break;
	}
	
	if (time) Hint.timer_id = setTimeout('HideHint()', time);
}
	
function HideHint() {
	if (Hint.timer_id) {
		window.clearTimeout(Hint.timer_id);
		Hint.timer_id = undefined;
	}
	Hint.style.display = 'none';
}
	
function SetHint() {
	document.body.appendChild(Hint);
}
	
if (typeof document.attachEvent != 'undefined') window.attachEvent('onload', SetHint);
else window.addEventListener('load', SetHint, false);


Использование:
<input name="test" type="text" onFocus="DataCheck(this, 'разреш. символы');" /> - без подсказки
<input name="test" type="text" onFocus="DataCheck(this, 'разреш. символы', true);" /> - с подсказкой

Про параметры dX, dY, spX, spY, time смотреть на proger.blog.ru в статье javascript: Подсказки


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