為頁面上某些文本框添加離開驗證輸入事件


今天朋友問我一個js的問題,他是這么描述的:

頁面上有些許文本框,但是要求獲得焦點后就必須為其輸入數據. 如果光標離開,
驗證是否已經填入數據,如果沒有填入數據就彈出提示對話框. 結束對話框后,
要求該文本框獲得焦點,可以繼續輸入.

起初我沒有在意,但是看了他的要求,我覺得應該很簡單吧!后來看了看,似乎並不容易.
問題出現在怎么添加事件執行代碼. 先貼一段代碼,
為id為text的div標簽下的所有文本框添加失去焦點的事件

 1 <html>
 2     <head>
 3         <title></title>
 4         <script type="text/javascript">
 5             function initialize() {
 6                 var text = document.getElementById("text").getElementsByTagName("input");
 7                 for(var i = 0; i < text.length; i++) {
 8                     text[i].onblur = function() {
 9                         // 失去焦點的事件
10                     }
11                 }
12             }
13             
14             onload = function() {
15                 initialize();
16             }
17         </script>
18     </head>
19     <body>
20         <div id="text">
21             <input type="text" /><br />
22             <input type="text" /><br />
23             <input type="text" /><br />
24             <input type="text" /><br />
25         </div>
26     </body>
27 </html>

      關於這個題目的問題就在於如何使文本框獲得焦點.
要求失去焦點的時候檢查是否有數據,沒有數據彈出對話框,並要求當前文本框獲得焦點
簡單的想法就是

1 text[i].onblur = function() {
2     // 長度為零表示沒有數據
3     if(this.value.length == 0) {
4         alert("請輸入數據");    // 彈出對話框
5         this.focus();            // 獲得焦點
6     }
7 }


感覺沒什么問題,但是一到瀏覽器中執行就悲劇了.
因為會死在一個窗體事件的調用上. 怎么回事兒呢?

原來第一個文本框獲得焦點的時候,如果沒有輸入數據,直接跳到第二個文本框
(或者是點擊頁面的其他地方,也或者讓光標離開瀏覽器),都會觸發離開的事件

1、如果是點擊文本框,將鼠標離開文本框點擊,也不點擊其他文本框
  -> 離開時首先判斷文本框中是否有數據,即value.length == 0
  -> 如果沒有數據,則彈出對話框"請輸入數據",同時文本框失去焦點
  -> 待用戶點擊確認后,該文本框獲得焦點
  這樣沒有什么問題,但是如果點擊的是下一個文本框就不一樣了

2、點擊第一個文本框,然后點擊另一個文本框(悲劇了)
  -> 第一個文本框失去焦點,第二個文本框得到焦點就觸發了事件
  -> 添加代碼,得到焦點的代碼,看看當第二個文本框獲得焦點時事件的觸發順序
    -> 先為每個文本框添加一個title屬性,並一次賦值: 1,2,3,4

1 <div id="text">
2     <input type="text" title="1" /><br />
3     <input type="text" title="2" /><br />
4     <input type="text" title="3" /><br />
5     <input type="text" title="4" /><br />
6 </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
    -> 由於所有方法都需要判斷,將變量定義成全局的

1 var current = null;

  -> 當文本框獲得焦點的時候,判斷current是否為null,為空時為其賦值,否則不變

if(!current) {
    current = this;
}

  -> 那么這個變量可以記錄第一次選中的文本框,在失去焦點的方法中,如果當前文本框與這個變量不匹配,就不彈出"請輸入數據"的對話框

1 if(this == current && this.value.length == 0) {        // 判斷是否是當前文本框,以及是否有數據
2     alert(this.title + "請輸入數據");
3     this.focus();
4 }

  -> 然后在正確輸入數據離開該文本框時,將current清空,賦值為null

1 if(this == current && this.value.length == 0) {
2     alert(this.title + "請輸入數據");
3     this.focus();
4 }
5 else {
6     current = null;
7 }

 

那么js代碼可以修改為

 1 <script type="text/javascript">
 2     var current = null;
 3     function initialize() {
 4         var text = document.getElementById("text").getElementsByTagName("input");
 5         for(var i = 0; i < text.length; i++) {
 6             text[i].onfocus = function() {
 7                 if(!current) {
 8                     current = this;
 9                 }
10             }
11             text[i].onblur = function() {
12                 if(this == current && this.value.length == 0) {
13                     alert(this.title + "請輸入數據");
14                     this.focus();
15                 }
16                 else {
17                     current = null;
18                 }
19             }
20         }
21     }
22     onload = function() {
23         initialize();
24     }
25 </script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM