2012-07-29 155 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