2012-07-29 51 views
4

我有一個文本框和一個Jquery UI對話框。當用戶輸入文本框並按下Enter鍵時,我想顯示對話框。爲了實現這個目標我使用下面的代碼:Focusout被觸發兩次

$(document).ready(function() { 
    var helpDial = $('#helpDialog'); 
    var input = $('#helpSearch'); 

    helpDial.dialog({ 
     width: 800, 
     autoOpen: false, 
     modal: true, 
     title: "Templates", 
     position: [165, 158] 
    }); 

    input.focusin(function() { 
     helpDial.dialog('close'); 
    }).focusout(function() { 
     helpDial.dialog('open'); 
    }).on('keypress', function (e) { 
     var code = (e.keyCode ? e.keyCode : e.which); 
     if (code == 13) { 
      input.focusout(); 
      return false; 
     } 
    }); 
}); 

<input id="helpSearch" /> 
<div id="helpDialog"></div> 

http://jsfiddle.net/7Fpm4/1

的問題是,當我按下Enter鍵,focusout被稱爲兩次,一次從input.focusout()和第二次helpDial.dialog('open')之後在focusout事件處理程序中。這會導致創建兩個背景疊加層,並且當關閉對話框時,一個疊加層仍然可見。

我在做什麼錯?有沒有更好的方法來處理這種情況 - 「在文本字段中按下一個輸入打開一個jQuery對話框」。謝謝。

+1

當輸入失去焦點並且用戶按下Enter鍵時,是否要顯示對話框? – banzomaikaka 2012-07-29 23:49:49

+0

是的,就是這樣 - 當文本框失去焦點或按下輸入時 – user1044169 2012-07-30 00:46:58

回答

3

防止事件觸發的唯一方法是解除綁定事件處理程序。或者,根據情況,根據事件發生時可用的信息採取差異化行動。

只要元素失去焦點,就會觸發focusout事件。在這種情況下,每當用戶點擊文本框時,觸發一個focusin事件。一旦光標離開文本框(當對話框打開時發生),觸發事件focusout

您的代碼存在的問題是您強行撥打focusout事件,然後在打開對話框時自然調用focusout事件。因此,如下修改代碼:

$(document).ready(function() { 
    var helpDial = $('#helpDialog'); 
    var input = $('#helpSearch'); 

    helpDial.dialog({ 
     width: 800, 
     autoOpen: false, 
     modal: true, 
     title: "Templates", 
     position: [165, 158] 
    }); 

    input.on('focusin', function() { 
     input.on("focusout", textboxFocusOut); 
    }).on('keypress', function (e) { 
     var code = (e.keyCode ? e.keyCode : e.which); 
     if (code == 13) { 
      textboxFocusOut(); 
     } 
    }); 

    function textboxFocusOut() { 
     input.off("focusout", textboxFocusOut); 
     helpDial.dialog('open');     
    } 

}); 

http://jsfiddle.net/8L7EL/1/

這段代碼是做一個函數結合focusoutfocusin處理內。如果用戶離開文本框,則將調用事件處理函數,該函數將立即解除綁定事件(以防止多次綁定該函數)。如果用戶點擊回車鍵,則手動調用該功能,該功能會在打開對話框之前刪除事件處理程序,以防止在對話框打開時自動觸發事件觸發器focusout

0

http://jsfiddle.net/7Fpm4/2/我更新您的例子,只是改變了input.focusin(函數()爲input.change(函數()

+0

這並不能真正解決問題。進入輸入字段,點擊'enter',然後關閉對話框。看到問題了嗎?重新加載並嘗試進入現場,然後單擊(不輸入)。我*認爲*這是問題所在。 – 2012-07-29 23:48:31

+0

如果你想在提交後清除輸入文本,添加input.val('');在返回false之前; – 2012-07-29 23:50:18

+0

是的,我明白了。我沒有看到, – 2012-07-29 23:51:41

3

最明顯的解決方案可能是使用像enter_pressed一個變量來通知focusout功能:

$(function() { 
    var helpDial = $('#helpDialog'), 
     input = $('#helpSearch'), 
     enter_pressed = false; 

    helpDial.dialog({ 
     width: 800, 
     autoOpen: false, 
     modal: true, 
     title: "Templates", 
     position: [165, 158] 
    }); 

    input.on('focusout', function() { 
     if(!enter_pressed) { 
      helpDial.dialog('open'); 
     } else { 
      enter_pressed = false; 
     } 
    }).on('keypress', function (e) { 
     var code = (e.keyCode ? e.keyCode : e.which); 
     if (code == 13) { 
      enter_pressed = true; 
      helpDial.dialog('open'); 
     } 
    }); 
}); 

http://jsfiddle.net/joplomacedo/7Fpm4/7/

不過,我相信有一個清晰的解決方案。我會盡力拿出它。

Aside
確實需要.focusin事件處理程序嗎?

+0

我沒有看到這個問題,因爲它不是全球範圍內的作品。 – 2012-07-30 00:10:15

+0

是的,我只是想知道是否有辦法阻止事件發生。那會更好。 – banzomaikaka 2012-07-30 00:12:11