Навигация по страницам топика <ctrl>+стрелки

magic

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

Существующий на сайте код с дополненительными двумя строками (выделил их жирным):


<script type="text/javascript"><!--
document.onkeydown = NavigateThrough;
var useHotKey=true;
function NavigateThrough (event)
{
  if(!window.useHotKey) return;
  if (!document.getElementById) return;
  if (window.event) event = window.event;
  if (event.ctrlKey && !event.shiftKey) {
    var link = null;
    var href = null;
    switch (event.keyCode ? event.keyCode : event.which ? event.which : null)
    {
      case 0x25: link = document.getElementById ('LinkPrev'); break;
      case 0x27: link = document.getElementById ('LinkNext'); break;
      case 0x26: link = document.getElementById ('LinkUp'  ); break;
      case 0x28: link = document.getElementById ('LinkNew' ); break;
      case 0x24: href = '/'; break;
    }
    if (link && link.href) document.location = link.href;
    if (href) document.location = href;
  }
}
// --></script>

Нижеследующий фрагмент новый для форума и его надо поставить обязательно в самый конец прямо перед </body> или как более корректный вариант по onload документа.
Работа скрипта: назначить всем полям форм onfocus и onblur функции, которые по вызову будут менять переменную useHotKey. В целом, этого будет достаточно, но можно втянуть в эту разметку и другие элементы документа если появится необходимость, например “чек-боксы” и “баттоны”.


<script type="text/javascript"><!--
var c = document.getElementsByTagName('textarea');
for (var i=0; i<c.length; i++) {
	c[i].onfocus = onFocusHandler;
	c[i].onblur = onBlurHandler;
}
var c = document.getElementsByTagName('input');
for (var i=0; i<c.length; i++) {
	if (c[i].type == 'text') {
		c[i].onfocus = onFocusHandler;
		c[i].onblur = onBlurHandler;
	}
}
function onFocusHandler() {
	window.useHotKey = false;
}
function onBlurHandler() {
	window.useHotKey = true;
}
// --></script>

PS: Протестировано локально в MSIE.
Как будет себя вести именно в этом в форуме - надо проверять.

Vitaly

Спасибо. Есть пара вопросов

  1. GetElementByTagName() не накрячится в какой-нибудь опере? Кажется, там были какие-то отличия.

  2. А не будет ли достаточно навесить хендлеры только на textarea в упрощенном и полном редакторе? Там вроде всего пара шаблонов должна быть, потому что стандартный код для всех случаев.

  3. А в каких браузерах вообще есть проблема? Только что заметил, что пользуюсь фаерфоксом и ни разу не сталкивался.

magic
Vitaly:

Спасибо. Есть пара вопросов

  1. GetElementByTagName() не накрячится в какой-нибудь опере? Кажется, там были какие-то отличия.

  2. А не будет ли достаточно навесить хендлеры только на textarea в упрощенном и полном редакторе? Там вроде всего пара шаблонов должна быть, потому что стандартный код для всех случаев.

  3. А в каких браузерах вообще есть проблема? Только что заметил, что пользуюсь фаерфоксом и ни разу не сталкивался.

  1. Проверил в Опере 9.10
    Работает, ошибок не обнаружил.

  2. Цикл ведется по объектам определенного типа, соответсвенно, довольно быстро и нагружать компьютер юзера не должен т.к. этих объектов в документе ограниченное кол-во. Можно, конечно, оставить только textarea, но в теме сообщения и в поле для поиска кто-то да попадется на горячие клавишу, что логически некорректно. Можно, конечно, просто взять и перечислить объекты вручную а не так вот универсально в цикле, но как-то хлопотно да и разница в быстродействии будет пшиковая.

  3. В файрфоксе 2.0 у меня ни текущий скрипт ни с моими доработаками не подает признаков жизни. Разбираться недосуг, если у Вас, Виталий, заработает - этого будет вполне достаточно для начала.

В целом, можно попробовать выложить эти обновления, бегло протетстить и уже по кол-ву фактических откликов от всеразличных броузеров пользователей посмотреть/подумать о доработках. Готов посодействовать в меру своего свободного времени.

PS: спасибо за отклик и потраченное время.

Vitaly

Ok. Я посмотрю, как это половчее прикрутить. В жабаскрипте не силен, так что ваша помощь с готовым кодом оказалась очень кстати.

Vitaly

Добавил блокировку. Можно проверять. Теперь если курсор стоит в области редактирования, то хоткеи должны блокироваться. Также выкинул Ctrl+Home как не особо нужное.

У кого с этим были проблемы - напишите, стало ли лучше, хуже, и какой браузер. Особенно интересуют различные версии IE и Оперы.

PS. Если все работает как надо - деньги и благодарности слать magic 😃

HikeR

Opera 10.00 Beta 2 - полет нормальный. ctrl + стрелки и home не перехватываются.

magic

MSIE 7.0.5730.11 - норм
Opera 9.10 - норм
FireFox 2.0 - норм

Виталий, спасибо за оперативное вмешательство.
Доброго дня.

29 days later
magic

Да, когда нажимаешь “Правка” своего сообщения - хоткеи по прежнему срабатывают.
Причем, дело не в Опере ибо и в мазиле и эксплорере тоже хоткеи срабатывают.

С лету пока понятно, что при интерактивном развертывании формы, новым элементам формы не назначены нужные нам события onfocus и onblur.
На вскидку направление решения на выбор:

  1. (долго но красиво) - в скрипте AJAX forum.rcdesign.ru/…/vbulletin_quick_edit.js надо что-то докрутить.
  2. (побыстрей но “коряво”) - по нажатию любой кнопки проверять фокус и если оный в элементе формы без ужных нам onfocus и onblur - их назначать =)

Готовый “рецепт” пока дать не готов - со свободным временем всегда туго.

Vitaly

Ну я пометил, с низким приоритетом, что надо исправить. Разберемсо. Как у программистов будет время - посмотрят, куда половчее кода навтыкать, чтобы цивилизованно все разрулить.

Vitaly

А не проще вообще на срабатывание хоткеев повесить проверку форкуса, где сработало? Зачем на элементы вешать обработчики дополнительные?

magic

Можно и так, конечно.
Осталось придумать как определять имя объекта с фокусом и добиться совместимости во всех обозревателях. Я на вскидку не припоминаю такой “фукнции”, хотя можно извернуться через document.addEventListener

А можно без изврата взять уже существующий код и меньшей кровью получить нужный результат, правда, очевидно далеко от изящества 😃 :
С инлайн-редактором не тестировал, но по идее должно сработать. Если не сработает, возвращаем всё обратно до появления более гениальных идей.


<script type="text/javascript"><!--
document.onkeydown = NavigateThrough;
function NavigateThrough (event)
{
var c = document.getElementsByTagName('textarea');
for (var i=0; i<c.length; i++) {
	c[i].onfocus = onFocusHandler;
	c[i].onblur = onBlurHandler;
}
var c = document.getElementsByTagName('input');
for (var i=0; i<c.length; i++) {
	if (c[i].type == 'text') {
		c[i].onfocus = onFocusHandler;
		c[i].onblur = onBlurHandler;
	}
}
  if(!window.useHotKey) return;
  if (!document.getElementById) return;
  if (window.event) event = window.event;
  if (event.ctrlKey && !event.shiftKey) {
    var link = null;
    var href = null;
    switch (event.keyCode ? event.keyCode : event.which ? event.which : null)
    {
      case 0x25: link = document.getElementById ('LinkPrev'); break;
      case 0x27: link = document.getElementById ('LinkNext'); break;
      case 0x26: link = document.getElementById ('LinkUp'  ); break;
      case 0x28: link = document.getElementById ('LinkNew' ); break;
      case 0x24: href = '/'; break;
    }
    if (link && link.href) document.location = link.href;
    if (href) document.location = href;
  }
}
function onFocusHandler() {
	window.useHotKey = false;
}
function onBlurHandler() {
	window.useHotKey = true;
}
// --></script>

И где-то в конце документа или по onload() поставить вызов дабы при первом нажатии хоткеи верно обрабатывались.


<script type="text/javascript"><!--
var useHotKey=false;
NavigateThrough();
useHotKey=true;
// --></script>

PS:
Такое решение мне лично не нравится, т.к. по каждому нажатию кнопки будет выполняться цикл по объектам документа и переназначаться обработчики. Но за неимением более грамотного варианта, этот может послужить пока народу. 😉
Конечно, лучше переназначить обработчики после вывода формы инлайн-редактора и на этом тема будет закрыта. Но, как я ранее и говорил, надо как-то поковыряться в скрипте AJAX или назначать обработчики после отработки этого скрипта. Тут надо малось “вдуматься”, но, к сожалению - нет когда времени.

1 month later
Vitaly

Вроде баг поправлен. Проверяйте. Теперь шорткаты должны блокироваться в абсолютно любом поле типа input или textarea.

new225

Опера 9.64, работает нормально… Но можно было бы на собачках все же сначала…