使用JavaScript模拟tab键

时间:2009-03-31 19:07:50

标签: javascript jquery html events keyboard

我希望浏览器的行为就像用户点击某些内容时按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 });

...我从here获取。

第一种方法似乎是最好的选择,但效果不佳。如果我将最后两个参数更改为98,98,确实在输入框中输入了'b'。但是,9,0和9,9(前者我从MDC网站上直接拿到的)都在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,在触发事件时它最终未定义。以下是我用来查看的代码:

$('#hi').keypress(function(e) {
  console.log(e);
});

还有其他想法吗?

5 个答案:

答案 0 :(得分:4)

我最终选择的解决方案是在我想要的区域的任一侧创建一个“焦点窃取器”div(tabindex = -1 - 可以有焦点,但最初不能选中)手动管理焦点。然后我在整个区域放置了一个冒泡真实的事件监听器,用于聚焦和模糊。当区域上出现任何焦点时,tabindex值将更改为-1,并且当出现任何模糊时,它们将更改为0.这意味着当聚焦在该区域时,您可以选择标签或移位标签。正确地结束其他页面元素或浏览器UI元素,但是一旦你聚焦在那里,焦点窃取者变得可能,并且在焦点上他们正确地设置手动区域并将焦点分流到他们结尾的元素,就像你点击了手动区域的一端或另一端一样。

答案 1 :(得分:3)

这是我在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在页面上找到下一个表单,但我们的大多数页面都使用单个表单。

答案 2 :(得分:1)

实际上,我猜有一种方法,即使它是一个主要的PITA。我可以确保每个元素,即使自然是一个制表符,都有一个Xtabindex,以某种方式以正确的顺序,即使我将丢弃其他人的小部件,所以使用jQuery事后添加这些,而不是能够在HTML或其他初始构建代码中指定它。然后,我的整个表格将有一个真正的tabindex。虽然它具有焦点,但它会吸收按键,如果它们是tab或shift + tab,则根据Xtabindex移动假焦点。如果在表单中的最后一个(或第一个上的shift +选项卡)元素上按下tab,它将不会吞噬击键,从而允许浏览器使用键盘正确地关注表单外的其他页面或浏览器UI元素。

我只能猜测这种方法会引入哪种非预期的副作用。

实际上,它甚至都不是解决方案,因为我仍然无法使用它伪造最后一个元素上的标签。

答案 3 :(得分:1)

我创建了一个simple jQuery plugin来解决这个问题。它使用jQuery UI的':tabbable'选择器来查找下一个'tabbable'元素并选择它。

使用示例:

// Simulate tab key when element is clicked 
$('.myElement').bind('click', function(event){
    $.tabNext();
    return false;
});

答案 4 :(得分:0)

我认为这些错误来自自动完成。您可以通过在发送事件之前将自动完成属性设置为“关闭”来关闭它们

setAttribute('autocomplete','off')