Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с горячими клавишами. Дефинитивный ответ. 
:(
    Опции темы
Sardar
Дата 28.1.2005, 17:52 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



Часто стал этот вопрос подниматься, потому рассмотрим сию проблему поближе. Существует 3 вида работы с горячими клавишами, от простой к сложной:
  • ловля всех ctrl+буква и ctrl+shift+буква
  • ловля любых комбинаций
  • ловля цепочек, последовательностей нажатий

В нормальных средах поддерживается только первый вариант + некоторые добавочные комбинации, будем называть его стандарным. То есть горячая клавиша начинается с нажатия ctrl. Исключения это клавишы Esc, F1-F12 и подобные; комбинации ctrl+shift, alt+shift, alt+ctrl - с исключениями работаем отдельно.

Второй способ предпологает накопление нажатых клавишь, а по первому onkeyup выполнять комбинацию.

Третий способ представляет собой иерархию буфферов для отлова всех возможных комбинаций, например по слову vingrad, что нибудь сделать. Это редко нужно, не используется в виндовых средах и сложно реализуемо. Например придётся отключать все браузерные горячие клавиши, что бы он не сбивал нас с комбинации.


Реализация стандартных горячих клавишь.

Задачу поставим так, при нажатой комбинации мы хотим что бы вызывалась наша функция, стандартная браузерная реакция, если она есть, отключается.

Что бы отключить дефолтное действие браузера нужно для Оперы и Мозиллы поймать событие onkeypress, для ИЕ это onkeydown - что гораздо удобнее для второго способа.

Заведём регистр, в корором регистрируются все запрашиваемые горячие клавиши, это будет обьект хешь-таблица, в которой ключём будет буква, а значением ссылка на функцию.

Код

//наш регистр
HotKeyHandler.keys = {};
//таблица преобразования для ИЕ, читай ниже
HotKeyHandler.convertIEKey={"1":65,"2":66,"4":68,"12":76,"16":80,"19":83,"20":84,"21":85,"26":90};
//обработчик горячих клавишь
function HotKeyHandler(ev) {
  var evt, key;
if(!(evt=window.event? window.event: ev)) return;
key = evt.keyCode? evt.keyCode: evt.charCode; //взяли код клавиши
       //ИЕ даёт код конрольных символов <32, преобразуем их к буквам
key=HotKeyHandler.convertIEKey[String(key)]? HotKeyHandler.convertIEKey[String(key)]: key;
   //если нажат ctrl или Esc - исключение из правил
   if (evt.ctrlKey||key==27) {
           //приводим ключ к верхему регистру, если нажат shift
    key=evt.shiftKey? String.fromCharCode(key).toUpperCase(): String.fromCharCode(key).toLowerCase();
           //зарегистрирован у нас такой обработчик?
    if(typeof(HotKeyHandler.keys[key]) == "function"){
       HotKeyHandler.keys[key](evt);
              //тогда отрубаем дефолтное действие браузера
    evt.cancelBubble = true; //отключить бег события выше для ИЕ
                  evt.returnValue = false; //отключить стандартное действие
                  //то же самое для Мозиллы
    if(evt.preventDefault) evt.preventDefault();
    if(evt.stopPropagation) evt.stopPropagation();
                  return false;
 }
   }
   return true;
}


Обработчик есть, теперь надо отловить события. События можно ловить на всём окне, либо на конкретном обьекте, например в текстовом поле. Вот пример как отловить для всего окна:
Код
//Default init. Handle hotkeys on document.
HotKeyHandler.windowInit=function() {
  //для Мозиллы и Оперы
  if(document.addEventListener && (getOperaVersion()>6||getOperaVersion()==0)) {
    document.addEventListener("keypress", HotKeyHandler, false);
  } else { //для ИЕ
    document.attachEvent("onkeydown", HotKeyHandler);
  }
}

function getOperaVersion() {
 var opver=navigator.userAgent.match(/Opera\s*([0-9.]+)/i);
 return (opver&&opver.length>1)? parseFloat(opver[1]): 0;
}

Оперу 6'ых версий поддерживать не стоит, но если кто сумеет поднять горячие под ней, пусть запостит решение сюда.

Как видим решение очень простое с минимальными напряжениями мозга smile
Используем:
Код
HotKeyHandler.keys = {
"a":function(){alert("Вы нажали ctrl+A");},
"B":function(){alert("Вы нажали ctrl+shift+B");},
"\x1B":function(){alert("Вы нажали клавишу Esc");}
};
HotKeyHandler.windowInit();

//жмём по клавишам =)


Горячие клавиши второго вида мы разберём попозже smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Pena
Дата 5.9.2006, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


КорнеплодЪ
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 20.4.2006
Где: эРэФия, аул Москв а...

Репутация: нет
Всего: нет



А что изменить чтобы работало сочитание "` + F1" F2, F3...  smile 
--------------------
Самовар по всем вопросам - сильно не ругайте 
PM   Вверх
Sardar
Дата 5.9.2006, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



В 13'oй и 15'ой строке проверяеться совпадение комбинации, добавь ||key=код_Fx_клавишы, либо выносим все "исключения" в отдеьный список и там проверяем.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Pena
Дата 5.9.2006, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


КорнеплодЪ
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 20.4.2006
Где: эРэФия, аул Москв а...

Репутация: нет
Всего: нет



Эм, из того что понял и сделал получилось: реакция на нажатие F1 (без сочетания с Ё (`)), но при этом всё такие пытается вылезти справка =( Как бы мне без всяких ctrl и schift+ctrl "забиндить" F1 + Ё  smile  ну по подобию того что вы здесь представили?)
--------------------
Самовар по всем вопросам - сильно не ругайте 
PM   Вверх
Sardar
Дата 5.9.2006, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



Pena, если returnValue=false; event.preventDefault() отработаны, то никаких справок не должно быть, выкладывай свой код.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Pena
Дата 7.9.2006, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


КорнеплодЪ
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 20.4.2006
Где: эРэФия, аул Москв а...

Репутация: нет
Всего: нет



То что имею на сейчас =\ (ctrl + 1,2,3..., и просто F1) 

Это вставляю на старнице:
Код

<script><!--
HotKeyHandler.keys = {
"1":function() { text.setSelectedText("<br>") },
"2":function() { text.setSelectedText("&nbsp; &nbsp; &nbsp;") },
"3":function() { text.setSelectedText("<a href=\"v.html\">", "</a><br>") },
"4":function() { text.setSelectedText("<b>", "</b>") },
"5":function() { text.setSelectedText("<span class=\"Antitalic\">", "</span>") },
"6":function() { text.setSelectedText("<span class=\"nog4epK\">", "</span>") },
"7":function() { text.setSelectedText("<sup>", "</sup>") },
"8":function() { text.setSelectedText("<div class=\"3a7ovoBoK\">", "</div>") },
"9":function() { text.setSelectedText("<span class=\"Block\">\n", "\n</span>") },
"0":function() { text.setSelectedText("<p class=\"P\">", "</p>") },
"\x70":function(){ alert("F1") }
};
HotKeyHandler.windowInit();
  --></Script>

А это отдельнo:
Код

<!--
// Взято с [URL=http://forum.vingrad.ru/index.php?showtopic=41008&unread=1&hl=]http://forum.vingrad.ru/index.php?showtopi...nread=1&hl=[/URL]
HotKeyHandler.convertIEKey={"1":65,"2":66,"4":68,"12":76,"16":80,"19":83,"20":84,"21":85,"26":90};

function HotKeyHandler(ev) {
var evt, key;
if(!(evt=window.event? window.event: ev)) return;
key = evt.keyCode? evt.keyCode: evt.charCode;
key=HotKeyHandler.convertIEKey[String(key)]? HotKeyHandler.convertIEKey[String(key)]: key;
if (evt.ctrlKey||key==112) {
key=evt.shiftKey? String.fromCharCode(key).toUpperCase(): String.fromCharCode(key).toLowerCase();
if(typeof(HotKeyHandler.keys[key]) == "function"){
HotKeyHandler.keys[key](evt);
evt.cancelBubble = true;
evt.returnValue = false;
if(evt.preventDefault) evt.preventDefault(); 
if(evt.stopPropagation) evt.stopPropagation();
return false;
}
}
return true;
}

HotKeyHandler.windowInit=function() {
if(document.addEventListener && (getOperaVersion()>6||getOperaVersion()==0)) {
document.addEventListener("keypress", HotKeyHandler, false);
}
else {
document.attachEvent("onkeydown", HotKeyHandler);
}
}
function getOperaVersion() {
var opver=navigator.userAgent.match(/Opera\s*([0-9.]+)/i);
return (opver&&opver.length>1)? parseFloat(opver[1]): 0;
}
-->


Это сообщение отредактировал(а) Pena - 7.9.2006, 17:33
--------------------
Самовар по всем вопросам - сильно не ругайте 
PM   Вверх
Sardar
Дата 10.9.2006, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



Проверил, твой код работает в ИЕ, мозилле, опере, но в ИЕ и Опере хелп показываеться по любому. Пробовал присвоить evt.keyCode = 0, всё равно не хочет.

В мозилле естественно всё хорошо.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Pena
Дата 23.9.2006, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


КорнеплодЪ
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 20.4.2006
Где: эРэФия, аул Москв а...

Репутация: нет
Всего: нет



А ежели мне надо кнопки к примеру F1 - F4 забиндить, что именно нужно "копировать-вставить"? =)
--------------------
Самовар по всем вопросам - сильно не ругайте 
PM   Вверх
Sardar
Дата 23.9.2006, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



Ничего, серьёзно, я бы рад вообще отклкючить F1(никогда не использую), т.к. стоит рядом с Esc (vim, транслит etc).

Остальные Fn должны быть перехватываемы, задай их коды и всё.


M
Sardar
Ступил, чтo бы перехватывать Fx клавиши необходимо их пропустить: if (evt.ctrlKey||key==27||(key >= 112 && key <= 123))
Условие пропускает все ctrl + (shift)? +, esc, F1 - F12.



--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Diddy
  Дата 8.4.2008, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 29.3.2008

Репутация: нет
Всего: нет



Sardar, афтар, спасиба, писшы исчо!
особенно хочу про ловлю цепочек, последовательностей нажатий!!! smile 


PM MAIL ICQ   Вверх
Kinjeiro
Дата 3.7.2009, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 3.7.2009

Репутация: нет
Всего: нет



Доброго дня

Код

key=evt.shiftKey? String.fromCharCode(key).toUpperCase(): String.fromCharCode(key).toLowerCase();

Мне кажется, в данном примере не учитывается нажатие CAPS LOCK.

Код

//для Мозиллы и Оперы
   if(document.addEventListener && (getOperaVersion()>6||getOperaVersion()==0)) {
     document.addEventListener("keypress", HotKeyHandler, false);
   } else { //для ИЕ
     document.attachEvent("onkeydown", HotKeyHandler);
   }

Для чего Вы вешаете в IE обработчик именно на keydown?
KeyCode в событии keyDown возврашает номер клавиатурной клавишу, но не реального символа.
При работе с  разнообразными локалями очень часть требуется получить именно реальный UniCode код (учитывающий и особенности локали, и case censetive) для правильной интерпритации введенного символа.
К примеру, во француской локале нажатие клавиатурной клавиши, на которой изображена цифра "2", без нажатия каких либо шифтов или альтов подразумеваете получение символа "é". Однако в keydown keyCode = 50, вместо правильного 233, который отображается лишь в keyCode события keypress)

Это сообщение отредактировал(а) Kinjeiro - 3.7.2009, 13:13
PM MAIL   Вверх
dandandan
  Дата 22.11.2009, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 22.11.2009
Где: Москва

Репутация: нет
Всего: нет



Какой код нужно добавить, чтобы отловить комбинацию ctrl + enter ?

PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Здесь публикуют скрипты, которые уже проверены в обсуждениях других тем (при этом полезно поставить ссылки на все смежные обсуждения) или переносятся кем-либо из модераторов по просьбе участников, если видно, что в результате обсуждения темы был написан полезный или интересный скрипт. Третий возможный вариант - участник форума публикует скрипт, заведомо известный как полезный и эффективный, для, возможно, небольшой доработки и обсуждения.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Наши скрипты | Следующая тема »


 




[ Время генерации скрипта: 0.0933 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.