как отделить нажатие символьных клавиш от функциональных?
Подскажите, пожалуйста, как отделить нажатие символьных клавиш от функциональных?
Пример: точка имеет KeyCode = 46, как и DEL, что мне делать, чтобы запретить точку и разрешить клавишу DEL? Заранее благодарен. |
46 в e.keyCode - это дэл.
46 в e.charCode - это точка. |
У меня charCode почему то везде выдает undefined
|
Вот небольшой тестовый скриптик написал:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>ТЕСТ</title> <script type="text/javascript" language="JavaScript1.2"> <!-- function data_check(n) { var echo = document.getElementById("echo" + n); var echoo = document.getElementById("echoo" + n); echo.innerHTML = event.keyCode; echoo.innerHTML = event.charCode; } //--> </script> </head> <body> <form> <input name="test" type="text" onKeyPress="data_check('')" onKeyDown="data_check('2')" onKeyUp="data_check('3')" /> </form> <div id="echo">- 1 -</div><div id="echoo">0</div> <div id="echo2">- 2 -</div><div id="echoo2">0</div> <div id="echo3">- 3 -</div><div id="echoo3">0</div> </body> </html> |
ну так в ИЕ его и нет :)
Смотри: запускай свой пример в ИЕ и нажимай дэл. Событие онкейпресс для него не происходит. Вот так и различай в ИЕ. |
Да и точка в ИЕ - это 190 :)
|
190 срабатывает на onKeyDown и onKeyUp, а на onKeyPress - 46
charCode все равно undefined, и не только в ИЕ, а так же и в опере, сработало только в Google Chrome. А в мозиле почему то вообще ничего не пашет. Если бы мне надо было бы только точку запретить - я бы обробатывал onKeyDown и не парился бы. Но суть в том, что я изначально запрещал в полях некоторые символы для ввода (например, было одно поле, в которое я разрешил вводить только цифры), делал это через onKeyPress, но когда тестировал - понял, что упраляющие клавиши теперь тоже не работают (запретив все кроме цифр в onKeyPress, я запретил и функциональные клавиши), тогда я их тут же разрешил, но вместе с функциональными клавишами добавились и нежелательные символы. И вот теперь передо мной стоит проблема как отделить нажатие символьных клавиш от функциональных, и почему в мозиле нифига не работает. |
http://javascript.ru/forum/project/1...nyjj-vvod.html
вот посмотри этот код. Он работает везде правильно. Может поймёшь, почему твой код не пашет в ФФ :) |
Ну что ж, спасибо. Попробую разобраться, хотя, если честно, врядли.
|
ZoNT можешь подписать коментарии, а то я вообще ничего разобрать немогу - некоторые операторы впервый раз вижу. А еще лучше - если не трудно, покалдуй над моим скриптом.
|
мне так лень... Я на выходных отдохнуть хочу. Если до понедельника не сделаешь, то в понедельник помогу :)
|
Так, ладно, в мозиле я заставил его работать и он тоже, оказывается отображает символы через charCode (что за несправедливость - почему в ИЕ и опере это не работает).
Так как же все таки разделять нажатия клавиш? :(( |
Слушай ZoNT, а ведь ты тоже получается в своем скрипте разделяеш как-то нажатия символьных и функциональных клавиш. Ведь кроме нужных символов, ничего не вводится, а функц. клавиши работают. У меня премерно таже задача, только без маски, без ограничения по длине (разве что с помощью св-ва maxlength input'а). Необходимо только ограничивать ввод символов.
Ты мог бы сделать скрипт, в который бы вместо маски задавались бы разрешенные символы, ну и как у тебя: a - любая буква, 9 - любая цифра, * - буква или цифра. И чтобы не было ограничений по длине и юзер мог бы вводить эти символы как захотел. Я думаю многие тебе за это спасибо скажут - я уж точно :) |
напиши требования по пунктам. Мы обсудим требования и я сделаю...
Без чётких требований получается "сделай то, не знаю что"... |
Функция с двумя параметрами (как у тебя):
1. ссылка на объект; 2. строка с разрешенными символами, все символы, кроме следующих разрешают только сами себя: 9 - разрешает ввод всех цифр; a - разрешает ввод всех букв русского и латинского алфавитов; z - разрешает ввод всех букв латинского алфавита; я - разрешает ввод всех букв русского алфавита; * - разрешает ввод всех букв русского и латинского алфавитов и всех цифр. Пример: 'z()-.' - разрешает ввод всех букв латинского алфавита, скобок ( и ), тире и точки. Функция должна только ограничивать ввод всех символов, не входящих в список разрешенных и больше ничего. При этом все функциональные клавиши должны работать (желательно, чтобы Ctrl+Z, Ctrl+C и Ctrl+V тоже). |
Потесть в разных браузерах, о багах пиши сюда...
function setMask(I,M){ M = M.split('').join('|'); if (/z/.test(M)) M = M.replace(/z/g,'[a-z]'); else if (/я/.test(M)) M = M.replace(/я/g,'[а-яё]'); else if (/a/.test(M)) M = M.replace(/a/g,'[a-zа-яё]'); else if (/\*/.test(M)) M = M.replace(/\*/g,'[a-zа-яё0-9]'); M = M.replace(/\(/g,'\\(').replace(/\)/g,'\\)').replace(/\//g,'\\/').replace(/9/g,'\\d').replace(/\./g,'\\.'); var r = new RegExp(M,'i'); function P(c,n){ if(c<38||c==39||(c==45&&n)||(c==46&&!n)||r.test(String.fromCharCode(c)))return true; return false } function V(){ setTimeout(function(k){ var a=I.value.split(''),x=[]; for(var i=0;i<a.length;i++)if(r.test(a[i]))x.push(a[i]); I.value=x.join('') },0) } I = typeof I=='string' ? document.getElementById(I) : I; I.onkeypress = function(e){ e=e||event; return P(e.keyCode||e.charCode,e.charCode); } if (document.all&&!window.opera) I.onpaste=V; else I.addEventListener('input',V,false) } |
1. В ИЕ вводятся след. символы, даже когда их не разрешаешь ! # $ % . " '
2. В опере и мозиле не работают Ctrl+Z, Ctrl+C и Ctrl+V, в ие и гугле работают. 3. В ИЕ при обновлении стронице, до ввода чего либо, первым символом можно поставить все, что угодно, а потом только начинается проверка, повторить такое нельзя, пока не обновишь страницу. |
В гугле, когда бэкспейсишь - курсор в конец прыгает, неудобно. При в встаках, кстати тоже. И в ИЕ при вставках курсор в конец смещается.
|
1) странно, точку проверял, работала...
2) в ФФ вставка работает. 3) не понял... надо значит всётаки хранить позицию :) |
Вот, потесть ещё:
function setMask(I,M){ M = M.split('').join('|'); if (/z/.test(M)) M = M.replace(/z/g,'[a-z]'); else if (/я/.test(M)) M = M.replace(/я/g,'[а-яё]'); else if (/a/.test(M)) M = M.replace(/a/g,'[a-zа-яё]'); else if (/\*/.test(M)) M = M.replace(/\*/g,'[a-zа-яё0-9]'); M = M.replace(/\(/g,'\\(').replace(/\)/g,'\\)').replace(/\//g,'\\/').replace(/9/g,'\\d').replace(/\./g,'\\.'); var r = new RegExp(M,'i'), d=document, c='character', y=-100000; function V(){ setTimeout(function(k){ var s=I.gC()[0]; var a=I.value.split(''),x=[]; for(var i=0;i<a.length;i++)if(r.test(a[i]))x.push(a[i]);else s--; I.value=x.join(''); I.sC(s); },0) } I = typeof I=='string' ? d.getElementById(I) : I; I.onkeypress = function(e){V();return true} I.sC = function(l,g){ if(this.setSelectionRange) this.setSelectionRange(l,l); else { g = this.createTextRange(); g.collapse(true); g.moveStart(c,y); g.move(c,l); g.select(); } } I.gC = function(r,b){ if (this.setSelectionRange) return [this.selectionStart,this.selectionEnd]; else { r = d.selection.createRange(); b = 0-r.duplicate().moveStart(c,y) return [b,b+r.text.length] } } if (d.all&&!window.opera) I.onpaste=V; else I.addEventListener('input',V,false) } |
ФФ:
1. позиция строки в поле при наборе длинного текста не смещается, т.е. курсор уходит за пределы поля 2. нельзя выделять с помощью Shift'а Опера: 1. при вводе запрещ. символа позиция строки уст. на начало (в отличии от ФФ при вводе разреш. символов позиция строки смещ., т.е. курсор находится в пределах поля) 2. нельзя выделять с помощью Shift'а 3. при нажатии Ctrl выделение снимается ИЕ: 1. с самого начала можно ввести один запрещенный символ, который сразу пропадает, если ввести еще что-нибудь 2. не работает Ctrl+Z в остальном ИЕ работает идельно, позиция строки в поле при наборе текста смещается как положено, на начало не прыгает при вводе запрещ. символов, выделение с шифтом работает вставка, копироване тоже работают ГУГЛ: В ГУГЛЕ все идеально Никаких лишних символов не пропускается ни в одном браузере!!! :) |
завтра ещё посмотрю...
|
Неполучается?
Напиши мне тогда комментарии (что, для чего и т. д.) - попробую разобраться. |
а, я просто занят был сильно на работе, сегодня посмотрю...
А по поводу ввода в ИЕ 1-го запрешённого символа - я такое поймать не смог. |
Цитата:
|
Цитата:
У меня в Опере ничего в начало не устанавливается... В ИЕ работает Ctrl+Z, но он работает только на отмену удаления. Как побороть пока не придумал. С шифтом сейчас разберусь. |
Вот с исправленным шифтом.
Про ИЕ (ctrl+Z) пока ничего не придумал. function setMask(I,M){ M = M.split('').join('|'); if (/z/.test(M)) M = M.replace(/z/g,'[a-z]'); else if (/я/.test(M)) M = M.replace(/я/g,'[а-яё]'); else if (/a/.test(M)) M = M.replace(/a/g,'[a-zа-яё]'); else if (/\*/.test(M)) M = M.replace(/\*/g,'[a-zа-яё0-9]'); M = M.replace(/\(/g,'\\(').replace(/\)/g,'\\)').replace(/\//g,'\\/').replace(/9/g,'\\d').replace(/\./g,'\\.'); var r = new RegExp(M,'i'), d=document, c='character', y=-100000; function V(){ setTimeout(function(k){ s=I.gC()[0]; var a=I.value.split(''),x=[]; for(var i=0;i<a.length;i++)if(r.test(a[i]))x.push(a[i]);else s--; I.value=x.join(''); I.sC(s); },0) } I = typeof I=='string' ? d.getElementById(I) : I; I.onkeypress = function(e){ e=e||event; if(e.ctrlKey||e.shiftKey)return true; V(); return true } I.sC = function(l,g){ if(this.setSelectionRange) this.setSelectionRange(l,l); else { g = this.createTextRange(); g.collapse(true); g.moveStart(c,y); g.move(c,l); g.select(); } } I.gC = function(r,b){ if (this.setSelectionRange) return [this.selectionStart,this.selectionEnd]; else { r = d.selection.createRange(); b = 0-r.duplicate().moveStart(c,y) return [b,b+r.text.length] } } if (d.all&&!window.opera) I.onpaste=V; else I.addEventListener('input',V,false) } |
Да, с ФФ кнечно гон получился (самое плохое, что под ним дофига народа сидит), а в остальном все ништяг. Читал на англоязычных форумах, чего там только не написано про эту тему, но более менее работающей функции пока никто не представил. Жуткий все-таки этот язык javascript, чтобы написать то, на что в других языках (к примеру Delphi) уйдет пара строк, здесь необходимо ТАК выебнуться - УЖОСС!!!
Но ты вообще гений! :)) |
Просто задача очень нестандартная и нетривиальная. Язык под такие задачи не заточен. А делфи более широкопрофильный...
|
Появилась идейка, как обойти баг в ФФ. Ты я так понял переписываешь значение инпута заново, поэтому в ФФ строка относительно границ элемента не съезжает. Но зато в ФФ работает charCode. Что если сделать проверку, если charCode не undefined, тогда корректируем символы с помощью него на лету, иначе уже написанным методом. По моему это должно сработать.
|
фишка в том, что строка в ФФ не съезжает (а должна), когда курсор устанавливается в нужную позицию (за пределы поля).
"На лету" не получится корректировать, так как при вставке тогда курсор будет уезжать (так как при вставке никакого charCode не будет) |
А я еще вывод подсказки добавил!!! :D
function setMask(I,M){ M = M.split(''); M2 = M.join('|'); if (/z/.test(M2)) M2 = M2.replace(/z/g,'[a-z]'); else if (/я/.test(M2)) M2 = M2.replace(/я/g,'[а-яё]'); else if (/a/.test(M2)) M2 = M2.replace(/a/g,'[a-zа-яё]'); else if (/\*/.test(M2)) M2 = M2.replace(/\*/g,'[a-zа-яё0-9]'); M2 = M2.replace(/\(/g,'\\(').replace(/\)/g,'\\)').replace(/\//g,'\\/').replace(/9/g,'\\d').replace(/\./g,'\\.'); var r = new RegExp(M2,'i'), d=document, c='character', y=-100000; function V(){ setTimeout(function(k){ s=I.gC()[0]; var a=I.value.split(''),x=[]; for(var i=0;i<a.length;i++)if(r.test(a[i]))x.push(a[i]);else {s--; ShowHint(I, M); } I.value=x.join(''); I.sC(s); },0) } I = typeof I=='string' ? d.getElementById(I) : I; I.onkeypress = function(e){ e=e||event; if(e.ctrlKey||e.shiftKey)return true; V(); return true } I.sC = function(l,g){ if(this.setSelectionRange) this.setSelectionRange(l,l); else { g = this.createTextRange(); g.collapse(true); g.moveStart(c,y); g.move(c,l); g.select(); } } I.gC = function(r,b){ if (this.setSelectionRange) return [this.selectionStart,this.selectionEnd]; else { r = d.selection.createRange(); b = 0-r.duplicate().moveStart(c,y) return [b,b+r.text.length] } } if (d.all&&!window.opera) I.onpaste=V; else I.addEventListener('input',V,false) } var Hint = document.createElement('div'); Hint.style.display = 'none'; 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'; function ShowHint(I, M) { if (Hint.timer_id) { window.clearTimeout(Hint.timer_id); Hint.style.display = 'none'; } var w = parseInt(I.offsetWidth); var h = parseInt(I.offsetHeight); var t = 0; var l = 0; var obj = I; while(obj) { t += parseInt(obj.offsetTop); l += parseInt(obj.offsetLeft); obj = obj.offsetParent; } if (M != '') { var MSG = 'Разрешено вводить только следующие символы: '; for (i = 0; i < M.length; i++) { if (i > 0) MSG += ' '; if (M[i] == 'a') MSG += '<strong>буквы русского и латинского алфавитов</strong>'; else if (M[i] == 'z') MSG += '<strong>буквы латинского алфавита</strong>'; else if (M[i] == 'я') MSG += '<strong>буквы русского алфавита</strong>'; else if (M[i] == '9') MSG += '<strong>цифры</strong>'; else if (M[i] == '*') MSG += '<strong>буквы русского и латинского алфавитов цифры</strong>'; else if (M[i] == ' ') MSG += '<strong>знак пробела</strong>'; else MSG += '<strong>' + M[i] + '</strong>'; } } else MSG = 'Запрещено вводить какие-либо символы.'; Hint.style.top = t + 2 + 'px'; Hint.style.left = l + w + 10 + 'px'; Hint.innerHTML = MSG; Hint.style.display = 'block'; Hint.timer_id = setTimeout('HideHint()', 4000); } function HideHint() { Hint.style.display = 'none'; Hint.timer_id = undefined; } function SetHint() { document.body.appendChild(Hint); } if (typeof document.attachEvent != 'undefined') window.attachEvent('onload', SetHint); else window.addEventListener('load', SetHint, false); |
чуть чуть затупил:
if (M != '') { var MSG = 'Разрешено вводить только следующие символы: <strong>'; for (i = 0; i < M.length; i++) { if (i > 0) MSG += ' '; if (M[i] == 'a') MSG += 'буквы русского и латинского алфавитов'; else if (M[i] == 'z') MSG += 'буквы латинского алфавита'; else if (M[i] == 'я') MSG += 'буквы русского алфавита'; else if (M[i] == '9') MSG += 'цифры'; else if (M[i] == '*') MSG += 'буквы русского и латинского алфавитов цифры'; else if (M[i] == ' ') MSG += 'знак пробела'; else MSG += M[i]; } MSG += '</strong>'; } else MSG = 'Запрещено вводить какие-либо символы.'; |
Вот написал ф-цию в ФФ работает на ура, но не знаю как вставить в твою:
function data_check(e, I, M) { if (e.charCode && !e.ctrlKey) { M = M.split(''); var BOOL = false; for (i = 0; i < M.length; i++) { if (M[i] == 'a' && ((e.charCode >= 65 && e.charCode <= 90) || (e.charCode >= 97 && e.charCode <= 122) || (e.charCode >= 1040 && e.charCode <= 1103))) { BOOL = true; break; } else if (M[i] == 'z' && ((e.charCode >= 65 && e.charCode <= 90) || (e.charCode >= 97 && e.charCode <= 122))){ BOOL = true; break; } else if (M[i] == 'я' && (e.charCode >= 1040 && e.charCode <= 1103)) { BOOL = true; break; } else if (M[i] == '9' && (e.charCode >= 48 && e.charCode <= 57)) { BOOL = true; break; } else if (M[i] == '*' && ((e.charCode >= 48 && e.charCode <= 57) || (e.charCode >= 65 && e.charCode <= 90) || (e.charCode >= 97 && e.charCode <= 122) || (e.charCode >= 1040 && e.charCode <= 1103))) { BOOL = true; break; } else if (M[i].charCodeAt() == e.charCode) { BOOL = true; break; } } if (!BOOL) ShowHint(I, M); return BOOL; } } |
А да я ступил немного, непонял сначала - в моей ф-ции ввести-то нельзя запреш. символы, а вставить можно. Вот хрень то.
|
Как ты узнаешь текущую позицию курсора в строке - решил попробовать написать ф-цию смещения строки, за счет изменения text-indent.
|
I.gC = function(r,b){ if (this.setSelectionRange) return [this.selectionStart,this.selectionEnd]; else { r = d.selection.createRange(); b = 0-r.duplicate().moveStart(c,y) return [b,b+r.text.length] } } |
Все ништяг - ФФ не отсекается. Чуток разобрался в твоем коде и дописал ф-цию позиционирования строки. Вот весь код:
var TMP = document.createElement('span'); TMP.style.position = 'absolute'; TMP.style.top = '-50px'; function setMask(I,M){ M = M.split(''); M2 = M.join('|'); if (/z/.test(M2)) M2 = M2.replace(/z/g,'[a-z]'); else if (/я/.test(M2)) M2 = M2.replace(/я/g,'[а-яё]'); else if (/a/.test(M2)) M2 = M2.replace(/a/g,'[a-zа-яё]'); else if (/\*/.test(M2)) M2 = M2.replace(/\*/g,'[a-zа-яё0-9]'); M2 = M2.replace(/\(/g,'\\(').replace(/\)/g,'\\)').replace(/\//g,'\\/').replace(/9/g,'\\d').replace(/\./g,'\\.'); var r = new RegExp(M2,'i'), d=document, c='character', y=-100000; function V(){ setTimeout(function(k){ s=I.gC()[0]; var a=I.value.split(''),x=[]; for(var i=0;i<a.length;i++)if(r.test(a[i]))x.push(a[i]);else {s--; ShowHint(I, M); } I.value=x.join(''); I.sC(s); },0) } function LinePos(pos) { TMP.innerHTML = '<pre style="font-family: Microsoft Sans Serif; font-size: 10pt;">' + I.value.substr(0, pos) + '</pre>'; l = parseInt(TMP.offsetWidth); if (l > I.offsetWidth) I.style.textIndent = '-' + (l - I.offsetWidth + 6) + 'px'; else I.style.textIndent = '0px'; } I = typeof I=='string' ? d.getElementById(I) : I; I.onkeypress = function(e){ e=e||event; if(e.ctrlKey||e.shiftKey)return true; V(); return true } I.sC = function(l,g){ if(this.setSelectionRange) this.setSelectionRange(l,l); else { g = this.createTextRange(); g.collapse(true); g.moveStart(c,y); g.move(c,l); g.select(); } if (navigator.userAgent.indexOf('Firefox') >= 0) LinePos(l); } I.gC = function(r,b){ if (this.setSelectionRange) return [this.selectionStart,this.selectionEnd]; else { r = d.selection.createRange(); b = 0-r.duplicate().moveStart(c,y) return [b,b+r.text.length] } } if (d.all&&!window.opera) I.onpaste=V; else I.addEventListener('input',V,false) } var Hint = document.createElement('div'); Hint.style.display = 'none'; Hint.style.cursor = 'default'; 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.onmousedown = function(){ HideHint(); } function ShowHint(I, M) { if (Hint.timer_id) { window.clearTimeout(Hint.timer_id); Hint.timer_id = undefined; Hint.style.display = 'none'; } var w = parseInt(I.offsetWidth); var h = parseInt(I.offsetHeight); var t = 0; var l = 0; var obj = I; while(obj) { t += parseInt(obj.offsetTop); l += parseInt(obj.offsetLeft); obj = obj.offsetParent; } var MSG = 'Разрешено вводить только следующие символы: <strong>'; for (i = 0; i < M.length; i++) { if (i > 0) MSG += ' '; if (M[i] == 'a') MSG += 'буквы русского и латинского алфавитов'; else if (M[i] == 'z') MSG += 'буквы латинского алфавита'; else if (M[i] == 'я') MSG += 'буквы русского алфавита'; else if (M[i] == '9') MSG += 'цифры'; else if (M[i] == '*') MSG += 'буквы русского и латинского алфавитов цифры'; else if (M[i] == ' ') MSG += 'знак пробела'; else MSG += M[i]; } MSG += '</strong>'; Hint.style.top = t + 2 + 'px'; Hint.style.left = l + w + 5 + 'px'; Hint.innerHTML = MSG; Hint.style.display = 'block'; Hint.timer_id = setTimeout('HideHint()', 5000); } function HideHint() { window.clearTimeout(Hint.timer_id); Hint.style.display = 'none'; Hint.timer_id = undefined; } function SetEls() { document.body.appendChild(TMP); document.body.appendChild(Hint); } if (typeof document.attachEvent != 'undefined') window.attachEvent('onload', SetEls); else window.addEventListener('load', SetEls, false); Едиственный недостаток - строгая зависимость от шрифта, используемого в инпуте. Здесь настроено для стандартного шрифта, но если кто-то будет использовать эту ф-цию и при этом переопределит шрифт для инпута, ему придется указать тот же шрифт в след. строке: TMP.innerHTML = '<pre style="font-family: Microsoft Sans Serif; font-size: 10pt;">' + I.value.substr(0, pos) + '</pre>'; Это самая первая строка в ф-ции LinePos |
Если придуиаешь что-нибудь с Ctrl-Z для IE, пиши. Огромное спасибо за помощь. Скажи куда тебе можно компенсацию кинуть :)
|
никуда... Я ж не говорил что за деньги это буду делать...
|
Часовой пояс GMT +3, время: 15:51. |