zoukankan      html  css  js  c++  java
  • 为页面上某些文本框添加离开验证输入事件

    今天朋友问我一个js的问题,他是这么描述的:
     
    页面上有些许文本框,但是要求获得焦点后就必须为其输入数据. 如果光标离开,
    验证是否已经填入数据,如果没有填入数据就弹出提示对话框. 结束对话框后,
    要求该文本框获得焦点,可以继续输入.
     
    起初我没有在意,但是看了他的要求,我觉得应该很简单吧!后来看了看,似乎并不容易.
     
    问题出现在怎么添加事件执行代码. 先贴一段代码,
    为id为text的div标签下的所有文本框添加失去焦点的事件
     
    <html>
    <head>
    <title></title>
    <script type="text/javascript">
    function initialize() {
    var text = document.getElementById("text").getElementsByTagName("input");
    for(var i = 0; i < text.length; i++) {
    text[i].onblur = function() {
    // 失去焦点的事件
    }
    }
    }
     
    onload = function() {
    initialize();
    }
    </script>
    </head>
    <body>
    <div id="text">
    <input type="text" /><br />
    <input type="text" /><br />
    <input type="text" /><br />
    <input type="text" /><br />
    </div>
    </body>
    </html>
     
    关于这个题目的问题就在于如何使文本框获得焦点. 
    要求失去焦点的时候检查是否有数据,没有数据弹出对话框,并要求当前文本框获得焦点
    简单的想法就是
     
    text[i].onblur = function() {
    // 长度为零表示没有数据
    if(this.value.length == 0) {
    alert("请输入数据");// 弹出对话框
    this.focus();// 获得焦点
    }
    }
     
    感觉没什么问题,但是一到浏览器中执行就悲剧了. 
    因为会死在一个窗体事件的调用上. 怎么回事儿呢?
     
    原来第一个文本框获得焦点的时候,如果没有输入数据,直接跳到第二个文本框
    (或者是点击页面的其他地方,也或者让光标离开浏览器),都会触发离开的事件
    1、如果是点击文本框,将鼠标离开文本框点击,也不点击其他文本框
    -> 离开时首先判断文本框中是否有数据,即value.length == 0
    -> 如果没有数据,则弹出对话框"请输入数据",同时文本框失去焦点
    -> 待用户点击确认后,该文本框获得焦点
    这样没有什么问题,但是如果点击的是下一个文本框就不一样了
    2、点击第一个文本框,然后点击另一个文本框(悲剧了)
    -> 第一个文本框失去焦点,第二个文本框得到焦点就触发了事件
    -> 添加代码,得到焦点的代码,看看当第二个文本框获得焦点时事件的触发顺序
    -> 先为每个文本框添加一个title属性,并一次赋值: 1,2,3,4
    <div id="text">
    <input type="text" title="1" /><br />
    <input type="text" title="2" /><br />
    <input type="text" title="3" /><br />
    <input type="text" title="4" /><br />
    </div>
    -> 再添加js代码
    function initialize() {
    var text = document.getElementById("text").getElementsByTagName("input");
    for(var i = 0; i < text.length; i++) {
    text[i].onfocus = function() {
    alert(this.title + "获得焦点");
    }
    text[i].onblur = function() {
    alert(this.title + "请输入数据");
    this.focus();
    }
    }
    }
    -> 使用IE8浏览器测试,鼠标离开首先弹出对话框"1请输入数据"
    -> 随后是"2获得焦点", "2请输入数据", "1获得焦点", "1请输入数据", "2获得焦点", "2请输入数据", ...如此反复
    -> 分析一下执行过程
    -> 鼠标点击第二个文本框,触发失去焦点方法,弹出对话框"1请输入数据"
    -> 点击弹出对话框确定按钮后,浏览器激活,第二个文本框获得焦点,触发方法,显示"2获得焦点",但是第一步中方法this.focus()没有执行
    -> 结束这个弹出对话框,this.focus()方法被执行,由于this指第一个文本框,因此第一个文本框获得焦点
    -> 焦点离开第二个文本框,触发离开的事件,显示"2请输入数据"
    -> 结束后第一个文本框获得焦点,显示"1获得焦点",但是刚刚离开第二个方法的this.focus()方法没有执行
    -> 因此结束弹出对话框后,执行this.focus()方法,第二个文本框获得焦点,继续离开第一个对话框,触发事件
    -> 可以了解到,这里就进入了死循环,不断在两个文本框中跳来跳去
     
    要解决这个问题,基本上就是在离开的时候获得焦点的情况
    -> 期望的执行,应该是:第一个文本框获得焦点,点击第二个文本框,由于第一个文本框中没有数据,弹出对话框
    -> 对话框结束,第二个文本框获得焦点,执行第一个对话框中的this.focus()方法,此时跳回第一个文本框
    -> 关键点来了,在这里从第二个文本框中失去焦点,第一个文本框获得焦点时,不应该触发离开第二个文本框的事件
     
    由于文本框添加方法是一起添加的,因此这里需要考虑,应该离开文本框时不是总是弹出对话框,也就是说,除了value.length == 0外还需要一个条件
    理一理思路,要求应该是
    -> 文本框离开的时候应该判断一下,应该操作的文本框是哪一个
    -> 例如,开始点击第一个文本框时,应该操作的是第一个文本框
    -> 当点击第二个文本框时,判断一下,当前操作文本框是不是第一个文本框
    -> 显然是,因此弹出对话框"1请输入数据",然后第二个文本框获得焦点
    -> 第一个方法的this.focus()方法执行,第二个文本框失去焦点,第一个文本框获得焦点
    -> 此时离开第二个文本框的时候,判断当前文本框. 显然当前文本框是第一个,因此不用弹出对话框
     
    有了这个思路,就知道了,只要添加一个全局变量记录当前对花框即可
    但是什么时候为这个变量赋值呢?当然是第一次获得焦点的时候. 不过这是有点疑虑. 
    -> 在第一个文本框选中的时候,点击第二个文本框时,不应该为这个变量赋值
    -> 但是一开始第一个文本框获得焦点时,需要为这个变量赋值
    -> 如果第一个文本框正常输入数据后,切刀第二个文本框,应该为这个变量赋值
    因此基本操作为
    -> 定义一个变量current,赋值为null
    -> 由于所有方法都需要判断,将变量定义成全局的
    var current = null;
    -> 当文本框获得焦点的时候,判断current是否为null,为空时为其赋值,否则不变
    if(!current) {
    current = this;
    }
    -> 那么这个变量可以记录第一次选中的文本框,在失去焦点的方法中,如果当前文本框与这个变量不匹配,就不弹出"请输入数据"的对话框
    if(this == current && this.value.length == 0) {// 判断是否是当前文本框,以及是否有数据
    alert(this.title + "请输入数据");
    this.focus();
    }
    -> 然后在正确输入数据离开该文本框时,将current清空,赋值为null
    if(this == current && this.value.length == 0) {
    alert(this.title + "请输入数据");
    this.focus();
    }
    else {
    current = null;
    }
     
    那么js代码可以修改为
    <script type="text/javascript">
    var current = null;
    function initialize() {
    var text = document.getElementById("text").getElementsByTagName("input");
    for(var i = 0; i < text.length; i++) {
    text[i].onfocus = function() {
    if(!current) {
    current = this;
    }
    }
    text[i].onblur = function() {
    if(this == current && this.value.length == 0) {
    alert(this.title + "请输入数据");
    this.focus();
    }
    else {
    current = null;
    }
    }
    }
    }
    onload = function() {
    initialize();
    }
    </script>
     

  • 相关阅读:
    centos crash debug
    go get Unknown SSL protocol error in connection to gopkg.in
    Tensorflow serving with Kubernetes
    Spring 集成 Swagger UI
    Docker Registry V2 Garbage Collection
    Docker Registry V2 with Nginx
    Zabbix磁盘性能监控
    Zabbix CPU utilization监控参数
    Windows挂载Gluster复制卷
    Redis持久化存储(三)
  • 原文地址:https://www.cnblogs.com/luseike/p/2725102.html
Copyright © 2011-2022 走看看