什么是与DOM的getNextSibling等效的FORM?

时间:2016-03-05 18:32:55

标签: javascript forms dom

我有一张表格,如下:

<FORM name="form1">
    <TABLE onkeypress="focusNextFormElement(event)">
        <TR>
            <TD><INPUT name="SomeObscureName"></TD><TD>Some data</TD>
        </TR>
        <TR>
            <TD><INPUT name="ThisName"><span>Here's some obscure text.</span></TD><TD>Some data</TD>
        </TR>
        <TR>
            <TD><INPUT name="someNameIdontKnow"></TD><TD>Some data</TD>
        </TR>
    </TABLE>
</FORM>

是否有更好,更有效的方法来编写此功能? (当然,这是一个简化的例子)

function focusNextFormElement(ev){
    var el = ev.target;
    var f = el.form;
    var xx = f.elements.length - 1;
    for(var x = 0; x < xx; x++){
        if(f.elements[x] === el){
            f.elements[x+1].focus();
        }
    }
}

此表单上可能有数千个元素,并且我不认为每次函数运行时循环遍历它们都非常有效。

另外,我可以用鼠标任意选择输入,因此跟踪数组可能用处不大。

我无法控制页面的生成,因为它是一个帮助自动化其他页面的油脂单脚本。

修改 感谢@Trincot,从更广泛的角度来看,@ Oriol,找到了答案。

function nextFormSibling(el){
    var elems = el.form.elements;
    var idx = [].indexOf.call(elems, el);
    return elems[idx+1] || el;
}

function previousFormSibling(el){
    var elems = el.form.elements;
    var idx = [].indexOf.call(elems, el);
    return elems[idx-1] || el;
}

4 个答案:

答案 0 :(得分:1)

基本上,不,如果不知道DOM的修正,你需要elements集合中元素的索引才能访问下一个元素。迭代似乎是唯一的方法,但考虑使用indexOf而不是手动执行。

但是,如果要多次访问下一个元素,则只能执行一次并缓存结果:

var nextFormElement = (function() {
  var cache = new WeakMap();
  return function(el) {
    if(!cache.has(el)) {
      var els = el.form.elements,
          idx = [].indexOf.call(els, el);
      cache.set(el, els[idx+1] || null);
    }
    return cache.get(el);
  };
})();

如果不支持ES6,您可以使用普通对象而不是弱映射,其中值是下一个元素,键是一些标识符,您可以将这些标识符存储在元素中作为data-*属性。

然后,像

一样使用它
var next = nextFormElement(event.target);
if(next) next.focus();

var nextFormElement = (function() {
  var cache = new WeakMap();
  return function(el) {
    if(!cache.has(el)) {
      var els = el.form.elements,
          idx = [].indexOf.call(els, el);
      cache.set(el, els[idx+1] || null);
    }
    return cache.get(el);
  };
})();
document.forms.form1.addEventListener('keypress', function(event) {
  var next = nextFormElement(event.target);
  if(next) next.focus();
});
<form name="form1">
  <div>
    <input name="SomeObscureName" />
    <span>Some data</span>
  </div>
  <div>
    <input name="ThisName" />
    <span>Here's some obscure text.</span>
    <span>Some data</span>
  </div>
  <div>
    <input name="someNameIdontKnow" />
    <span>Some data</span>
  </div>
</form>

那就是说,这段代码完全突兀,我不推荐它。如果用户想要聚焦下一个文本可聚焦字段,他可以使用Tab键。如果他不想改变焦点而你为他做这件事,那就太烦人了。

答案 1 :(得分:1)

您可以在表单的元素集合中获取元素的索引,调用 indexOf()。虽然此集合不是本机JavaScript数组,但您可以像这样使用 indexOf.call

function nextFormElement(el) {
    var f = el.form;
    if (f) return f.elements[1+[].indexOf.call(f.elements, el)];
}

这是一个演示片段,使用此函数在单击表单元素时将焦点移动到下一个元素。这显然是没用的,但它表明它有效:

&#13;
&#13;
function nextFormElement(el) {
    var f = el.form;
    if (f) return f.elements[1+[].indexOf.call(f.elements, el)];
}

function focusNextFormElement(ev){
    var el = nextFormElement(ev.target);
    if (el) el.focus();
}

document.querySelector('form').onclick = focusNextFormElement;
&#13;
<FORM name="form1">
    <TABLE onkeypress="focusNextFormElement(event)">
        <TR>
            <TD><INPUT name="SomeObscureName"></TD><TD>Some data</TD>
        </TR>
        <TR>
            <TD><INPUT name="ThisName"><span>Here's some obscure text.</span></TD><TD>Some data</TD>
        </TR>
        <TR>
            <TD><INPUT name="someNameIdontKnow"></TD><TD>Some data</TD>
        </TR>
    </TABLE>
</FORM>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

假设HTML严格遵循您的示例,您可以尝试:

function focusNextFormElement (ev) {
  // First find the tr element of this input...
  var tr = ev.target.parentNode.parentNode; // find the tr node
  // Advance to the next table row ...
  tr = tr.nextElementSibling
  // Then focus the input element in that row...  
  tr.querySelector ('input').focus ();

}

答案 3 :(得分:0)

你能详细说明你打算实现的目标吗?您想继续将输入焦点转移到输入元素吗?如果是这样,最好使用'tabindex'属性。

Rer:http://www.wufoo.com/html5/attributes/27-tabindex.html

如果没有,那么想了解更多关于这个问题。

注意:'TABLE'元素上的'onkeypress'有更多问题,因为对于输入字段中按下的每个键,它会立即切换到下一个输入字段。