Моделирование нажатия клавиш с помощью JavaScript
Я бы хотел, чтобы браузер работал так, как будто пользователь нажал клавишу Tab, когда они нажимают на что-то. В обработчике кликов я пробовал следующие подходы:
var event = document.createEvent('KeyboardEvent');
event.initKeyEvent("keypress", true, true, null, false, false, false, false, 9, 0);
this.input.focus()[0].dispatchEvent(event);
И jQuery:
this.input.focus().trigger({ type : 'keypress', which : 9 });
... который я взял из здесь.
Первый подход, кажется, лучший выбор, но не совсем работает. Если я изменил последние два параметра на 98, 98, действительно, в поле ввода вводится "b". Но 9, 0 и 9, 9 (первый из которых я взял прямо с веб-сайта MDC) оба дают мне эти ошибки в firebug под FF3:
Permission denied to get property XULElement.popupOpen
[Break on this error] this.input.focus()[0].dispatchEvent(event);
Permission denied to get property XULElement.overrideValue
[Break on this error] this.input.focus()[0].dispatchEvent(event);
Permission denied to get property XULElement.selectedIndex
[Break on this error] this.input.focus()[0].dispatchEvent(event);
Permission denied to set property XULElement.selectedIndex
[Break on this error] this.input.focus()[0].dispatchEvent(event);
Я слышал, что такие (без четкого определения "такие" ) события "ненадежны", что может объяснить эти ошибки.
Второй подход вызывает любое значение, которое я ставлю как event.which для передачи как event.which, но без эффекта (даже если я использую 98 вместо 9, в поле не вводится "b".) Если я попробуйте установить event.data в объекте, который я передаю, он заканчивается undefined, когда событие запускается. Ниже приведен код, который я использую для просмотра:
$('#hi').keypress(function(e) {
console.log(e);
});
Любые другие идеи?
Ответы
Ответ 1
Решение, с которым я столкнулся, состоит в том, чтобы создать div div "focus stealer" (с tabindex = -1 - может иметь фокус, но не может быть набран на первый план) по обе стороны от области, в которой я хочу для ручного управления фокусом. Затем я помещаю возбуждающий истину прослушиватель событий для фокусировки и размытия по всей области. Когда в области происходит какой-либо фокус, значения табуиндекса изменяются на -1, и когда происходит размытие, они меняются на 0. Это означает, что, сосредоточившись в области, вы можете вывести вкладку или сдвинуть-вкладку из нее и правильно заканчиваются на других элементах страницы или элементах пользовательского интерфейса браузера, но как только вы фокусируетесь оттуда, фокусщики становятся табулируемыми, и в фокусе они правильно настраивают область управления и шунтируют фокус на элемент на конце, как если бы вы нажали на один конец или другую область руководства.
Ответ 2
Это решение, которое я использовал в нашем webapp для двух настраиваемых элементов управления, всплывающего календаря и селектора всплывающих окон/значений (при нажатии на текстовое поле появляется div с двумя выборами)
function tab_focus(elem)
var fields = elem.form.getElements()
for(var i=0;i<fields.length;i++) {
if(fields[i].id == elem.id){
for(i=i+1;i<fields.length;i++){
if(fields[i].type != 'hidden'){
fields[i].focus()
return
}
}
break;
}
}
elem.form.focusFirstElement();
}
Это использует оболочку Prototype и ожидает в качестве параметра расширенный элемент (т.е. $('thing_id')).
Он получает форму, которой принадлежит элемент, и проходит через элементы формы до тех пор, пока не найдет себя.
Затем он ищет первый элемент после него, который не скрыт, и передает ему фокус.
Если в форме нет элементов после него, он перемещает фокус назад к первому элементу в форме. Вместо этого я мог бы найти следующую форму на странице через document.forms, но большинство наших страниц используют одну форму.
Ответ 3
На самом деле, я думаю, есть способ, даже если это крупная PITA. Я могу убедиться, что каждый элемент, даже если, естественно, табу-стоп, имеет Xtabindex, каким-то образом в правильном порядке, хотя я буду бросать в чужие виджеты и поэтому с помощью jQuery добавлять их после факта, а не быть в состоянии указать его прямо в HTML или другом исходном строительном коде. Тогда вся моя форма будет иметь настоящий tabindex. В то время как он имеет фокус, он будет поглощать нажатия клавиш, и если они являются вкладками или сдвигами +, переместите фальшивый фокус на основе Xtabindex. Если вкладка нажата на последней (или сдвиге + вкладке на первом) элементе в форме, она не будет сожрать нажатие клавиши, что позволяет браузеру правильно сфокусироваться на других элементах интерфейса страницы или браузера вне формы с помощью клавиатуры.
Я могу только догадываться, какие непредсказуемые побочные эффекты этот подход будет представлен.
Собственно, это даже не решение, потому что я все еще не могу подделать вкладку на последнем элементе, используя его.
Ответ 4
Я создал простой плагин jQuery, который решает эту проблему. Он использует селектор ": tabbable" jQuery UI, чтобы найти следующий элемент "tabbable" и выбирает его.
Пример использования:
// Simulate tab key when element is clicked
$('.myElement').bind('click', function(event){
$.tabNext();
return false;
});
Ответ 5
Я думаю, что эти ошибки взяты из автозаполнения. Вы можете отключить их, установив перед отправкой события атрибут автозаполнения на "off"
setAttribute('autocomplete','off')