首先获取带焦点的元素有很多种方式,比如:
document.activeElement;
关于focus事件,弄清楚点击提交按钮,或者鼠标在其他元素上触发了点击,再或者一旦通过其他方式转移了input元素的焦点时,之前带focus态的元素就变了。
现代浏览器还支持一个autofocus属性,文档加载到浏览器默认就有带焦点的元素了。
其次,转移焦点元素的方式有好几种,比如:鼠标点击,tab键切换至focusable元素,触摸等等。
回到问题上,就是如何获取带焦点的(focus态)的元素,然后拿到id就很好办了。但是在触发另外一个事件的时候(也就是这里的提交事件),很容易转移焦点元素,尤其是input,button,a等元素。
提供一种我认为稍微可靠一点的方案,以jQuery代码为例:
update:
假设有以下html:
button
$(function() {
// 处理autofocus
$('input').each(function() {
if($(this).prop('autofocus')) {
$(this).prop('focused', true);
} else {
$(this).prop('focused', false);
}
});
// 简单的借助focusout来获取当前退出焦点的元素
$('input').on('focusout', function() {
$(this).siblings('input').prop('focused', false);
$(this).prop('focused', true);
});
// 最后就是根据上面的处理获取结果
$('#btn').on('click', function() {
$('input').each(function() {
if($(this).prop('focused')) {
console.log($(this)[0].id);
}
});
});
// update
// 简单的处理回车
$(document).on('keyup', function(e) {
if(e.keyCode === 13) {
console.log($('input:focus'));
// 如果这里基于回车提交
// 通常焦点元素还在input元素上
// 当然也有可能改变了焦点元素的情况,比如原本基于回车来获取焦点元素的,但是在回车之前又(不小心)改变了焦点元素
// 此时就要基于这个情况尽量可靠的判断焦点元素是否预期的
}
});
});
上面的代码的代码很粗狂(仅作示例),欢迎各路大神指点。
思考:
首先我认为应该集中思考焦点元素的问题,也就是前面提到的元素的焦点可能转移的情况。
接下来楼上有同学也提到了使用键盘快捷提交(比如:回车,ctrl/cmd + enter等等),通过这种方式焦点元素不一定会改变(注意,我说的是不一定),那么此时又该如何处理焦点元素呢?在上面给出的示例代码中没有考虑这一点,但是了解到这些可变的因素之后就可以有很多思路了,换一种思路思考如何获取最后一次获取过焦点的input元素(即要提交值的input元素)。
嗯,刚起床,就说这么多了。更多的东西自己思考吧。
PS:第一次在这里回答问题,这个问题是在微博看到本站小编的推送之后点进来的。发现上面的一些方案还是有一些欠缺。但我也不保证我能给出完美的方案,纯粹是出于自己的想法给出思路。
补充:
如果考虑可用性,还有很多东要考虑进去。这里简单的考虑了当前会考虑的一些问题。具体的实现方式就有很多办法,弄清楚要解决的问题和可能碰到的问题,然后在碰到问题的时候干她就行了。
有同学在群里提出来,上面的代码中,autofocus属性只考虑了支持这个属性的情况。对于不支持这个属性的浏览器还可能在初始化的时候给特定的元素设置绑定focus态,比如:
$(function() {
$('#myInput').focus();
// 代码以jQuery为例
// 设置focused属性
$('input').prop('focused', false);
$('#myInput').prop('focused', true);
});
其实这个时候问题还是得回到目标元素(元素集合,也就是要处理的元素)的焦点问题。如果单纯的借助focusout,确保会触发focusout事件,其次就是正确的过滤元素。
此外,前面也提到了如果我通过键盘提交,焦点元素会不会改变?在提交的时候可以判断当前带focus态的元素(焦点元素)是不是目标元素。如果是,处理她。如果不是,那么焦点元素是哪个。
这中间,之所以会提到不能直接确定焦点元素的情况是出于其他代码改变了焦点,或者连带效果改变焦点元素等等情况。总之正确的拿到目标元素要处理的点还是比较多的。