Подтвердить что ты не робот

Моделирование нажатия клавиш с помощью 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);
});

Любые другие идеи?

4b9b3361

Ответ 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')