我有一张表格,如下:
<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;
}
答案 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)];
}
这是一个演示片段,使用此函数在单击表单元素时将焦点移动到下一个元素。这显然是没用的,但它表明它有效:
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;
答案 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'有更多问题,因为对于输入字段中按下的每个键,它会立即切换到下一个输入字段。