Навигация по страницам топика <ctrl>+стрелки
Можно доработать существующий код таким образом, чтобы горячие кнопки навигации не срабатывали при фокусе на полях формы.
Существующий на сайте код с дополненительными двумя строками (выделил их жирным):
<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.
Как будет себя вести именно в этом в форуме - надо проверять.
Спасибо. Есть пара вопросов
-
GetElementByTagName() не накрячится в какой-нибудь опере? Кажется, там были какие-то отличия.
-
А не будет ли достаточно навесить хендлеры только на textarea в упрощенном и полном редакторе? Там вроде всего пара шаблонов должна быть, потому что стандартный код для всех случаев.
-
А в каких браузерах вообще есть проблема? Только что заметил, что пользуюсь фаерфоксом и ни разу не сталкивался.
Спасибо. Есть пара вопросов
GetElementByTagName() не накрячится в какой-нибудь опере? Кажется, там были какие-то отличия.
А не будет ли достаточно навесить хендлеры только на textarea в упрощенном и полном редакторе? Там вроде всего пара шаблонов должна быть, потому что стандартный код для всех случаев.
А в каких браузерах вообще есть проблема? Только что заметил, что пользуюсь фаерфоксом и ни разу не сталкивался.
-
Проверил в Опере 9.10
Работает, ошибок не обнаружил. -
Цикл ведется по объектам определенного типа, соответсвенно, довольно быстро и нагружать компьютер юзера не должен т.к. этих объектов в документе ограниченное кол-во. Можно, конечно, оставить только textarea, но в теме сообщения и в поле для поиска кто-то да попадется на горячие клавишу, что логически некорректно. Можно, конечно, просто взять и перечислить объекты вручную а не так вот универсально в цикле, но как-то хлопотно да и разница в быстродействии будет пшиковая.
-
В файрфоксе 2.0 у меня ни текущий скрипт ни с моими доработаками не подает признаков жизни. Разбираться недосуг, если у Вас, Виталий, заработает - этого будет вполне достаточно для начала.
В целом, можно попробовать выложить эти обновления, бегло протетстить и уже по кол-ву фактических откликов от всеразличных броузеров пользователей посмотреть/подумать о доработках. Готов посодействовать в меру своего свободного времени.
PS: спасибо за отклик и потраченное время.
Ok. Я посмотрю, как это половчее прикрутить. В жабаскрипте не силен, так что ваша помощь с готовым кодом оказалась очень кстати.
Добавил блокировку. Можно проверять. Теперь если курсор стоит в области редактирования, то хоткеи должны блокироваться. Также выкинул Ctrl+Home как не особо нужное.
У кого с этим были проблемы - напишите, стало ли лучше, хуже, и какой браузер. Особенно интересуют различные версии IE и Оперы.
PS. Если все работает как надо - деньги и благодарности слать magic 😃
Opera 10.00 Beta 2 - полет нормальный. ctrl + стрелки и home не перехватываются.
MSIE 7.0.5730.11 - норм
Opera 9.10 - норм
FireFox 2.0 - норм
Виталий, спасибо за оперативное вмешательство.
Доброго дня.
rcopen.com/forum/f49/topic126658/277
Упс. Вызов инлайнового редактора похоже сшибает хуки проверки фокуса.
Да, когда нажимаешь “Правка” своего сообщения - хоткеи по прежнему срабатывают.
Причем, дело не в Опере ибо и в мазиле и эксплорере тоже хоткеи срабатывают.
С лету пока понятно, что при интерактивном развертывании формы, новым элементам формы не назначены нужные нам события onfocus и onblur.
На вскидку направление решения на выбор:
- (долго но красиво) - в скрипте AJAX forum.rcdesign.ru/…/vbulletin_quick_edit.js надо что-то докрутить.
- (побыстрей но “коряво”) - по нажатию любой кнопки проверять фокус и если оный в элементе формы без ужных нам onfocus и onblur - их назначать =)
Готовый “рецепт” пока дать не готов - со свободным временем всегда туго.
Ну я пометил, с низким приоритетом, что надо исправить. Разберемсо. Как у программистов будет время - посмотрят, куда половчее кода навтыкать, чтобы цивилизованно все разрулить.
А не проще вообще на срабатывание хоткеев повесить проверку форкуса, где сработало? Зачем на элементы вешать обработчики дополнительные?
Можно и так, конечно.
Осталось придумать как определять имя объекта с фокусом и добиться совместимости во всех обозревателях. Я на вскидку не припоминаю такой “фукнции”, хотя можно извернуться через 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 или назначать обработчики после отработки этого скрипта. Тут надо малось “вдуматься”, но, к сожалению - нет когда времени.
Вроде баг поправлен. Проверяйте. Теперь шорткаты должны блокироваться в абсолютно любом поле типа input или textarea.
Опера 9.64, работает нормально… Но можно было бы на собачках все же сначала…