前端 - JavaScript 如何获取获得了焦点的 Input 框的 id?
PHP中文网
PHP中文网 2017-04-10 14:22:09
0
5
550

有多个 Input 框,想实现一个点击提交只提交当前获取了焦点的 Input 框的值。

PHP中文网
PHP中文网

认证高级PHP讲师

reply all(5)
刘奇

如果需要只提交選中的Input,可以讓所有不需要提交的Input都沒有name屬性。

附示例代碼

<!DOCTYPE HTML>


<form><input id="input1"><input id="input2"><button type="submit">Submit</button></form>




<script>
(function(){
    var q;
    window.addEventListener("focus", function(e){
        var p;

        e = e || window.event;

        p = e.target;

        if (p.nodeName === "INPUT") {
            p.name = p.id;    

            if (q)
                q.name = "";

            q = p;
        }

    }, true)
}())
</script>


這段代碼的意思是,先取消之前獲得focus的Input的name屬性(如果有),再添加當前input的name屬性。

這段代碼的優點在於,無論是回車提交,還是點擊按鈕提交,都能得到正確的結果
缺點是,提交按鈕必須用button不能用input(不過根據語義,input作按鈕也是輸入信息用的,和文本框地位相同,純粹功能性的本來就要用button纔對)
還有就是沒考慮舊版ie的兼容性,不過現成的Javascript類庫太多了,隨便用一個,修改幾行代碼就行了。

只有帶name屬性的input纔會被提交~chrome safari firefox測試通過~沒有ie,不過新版ie應該也行

另:如果有多個form,只有其中一個form是要選擇性提交的,那麼就把focus綁定到這個form上就行了,示例代碼綁定的是window,注意useCapture一定要設置爲true。

Ty80

设置另外一个无关元素,每次input框获取焦点的时候更改那个无关元素的属性为这个input框的name值,onsubmit的时候就根据这个无关元素内的name值做ajax提交就好啦~

Ty80

首先获取带焦点的元素有很多种方式,比如:

  1. document.activeElement;
  2. 关于focus事件,弄清楚点击提交按钮,或者鼠标在其他元素上触发了点击,再或者一旦通过其他方式转移了input元素的焦点时,之前带focus态的元素就变了。
  3. 现代浏览器还支持一个autofocus属性,文档加载到浏览器默认就有带焦点的元素了。

其次,转移焦点元素的方式有好几种,比如:鼠标点击,tab键切换至focusable元素,触摸等等。

回到问题上,就是如何获取带焦点的(focus态)的元素,然后拿到id就很好办了。但是在触发另外一个事件的时候(也就是这里的提交事件),很容易转移焦点元素,尤其是inputbuttona等元素。

提供一种我认为稍微可靠一点的方案,以jQuery代码为例:

update

假设有以下html

<input id="id1" type="text">
<input id="id2" type="text">
<input id="id3" type="text">
<input id="id4" type="text">
<button id="btn">button</button>
<!-- <input type="submit" id="btn" value="submit"> -->
$(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元素上
            // 当然也有可能改变了焦点元素的情况,比如原本基于回车来获取焦点元素的,但是在回车之前又(不小心)改变了焦点元素
            // 此时就要基于这个情况尽量可靠的判断焦点元素是否预期的
        }
    });
});

上面的代码的代码很粗狂(仅作示例),欢迎各路大神指点。

思考

  1. 首先我认为应该集中思考焦点元素的问题,也就是前面提到的元素的焦点可能转移的情况。
  2. 接下来楼上有同学也提到了使用键盘快捷提交(比如:回车,ctrl/cmd + enter等等),通过这种方式焦点元素不一定会改变(注意,我说的是不一定),那么此时又该如何处理焦点元素呢?在上面给出的示例代码中没有考虑这一点,但是了解到这些可变的因素之后就可以有很多思路了,换一种思路思考如何获取最后一次获取过焦点的input元素(即要提交值的input元素)。

嗯,刚起床,就说这么多了。更多的东西自己思考吧。

PS:第一次在这里回答问题,这个问题是在微博看到本站小编的推送之后点进来的。发现上面的一些方案还是有一些欠缺。但我也不保证我能给出完美的方案,纯粹是出于自己的想法给出思路。

补充

如果考虑可用性,还有很多东要考虑进去。这里简单的考虑了当前会考虑的一些问题。具体的实现方式就有很多办法,弄清楚要解决的问题和可能碰到的问题,然后在碰到问题的时候干她就行了。

有同学在群里提出来,上面的代码中,autofocus属性只考虑了支持这个属性的情况。对于不支持这个属性的浏览器还可能在初始化的时候给特定的元素设置绑定focus态,比如:

$(function() {
    $('#myInput').focus();
    // 代码以jQuery为例
    // 设置focused属性
    $('input').prop('focused', false);
    $('#myInput').prop('focused', true);
});

其实这个时候问题还是得回到目标元素(元素集合,也就是要处理的元素)的焦点问题。如果单纯的借助focusout,确保会触发focusout事件,其次就是正确的过滤元素。

此外,前面也提到了如果我通过键盘提交,焦点元素会不会改变?在提交的时候可以判断当前带focus态的元素(焦点元素)是不是目标元素。如果是,处理她。如果不是,那么焦点元素是哪个。

这中间,之所以会提到不能直接确定焦点元素的情况是出于其他代码改变了焦点,或者连带效果改变焦点元素等等情况。总之正确的拿到目标元素要处理的点还是比较多的。

刘奇

$(':focus')

是这个意思吗?

迷茫

点击提交按钮的时候,提交按钮会获取焦点,所以你说的“当前获取焦点的元素”其实是应该是最后一次失去焦点的元素。

具体方法就是所有input元素绑定blur事件,记录当前元素的id,这样当点击提交按钮的时候,记录的id就是最后获得焦点的input元素。

var last_focused_element;
$('input').blur(function() {
    last_focused_element= $(this);
});

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template