【问题标题】:JQuery conflict between .hide() and .onclick().hide() 和 .onclick() 之间的 JQuery 冲突
【发布时间】:2015-07-28 10:35:04
【问题描述】:

所以我正在开发一个脚本,它在 Bootstrap 中使用下拉列表(typeahead_list 类)和文本框(et_email 类)。每当文本框失去焦点时,我都需要关闭下拉菜单。但是,如果有人单击下拉列表中的一个列表项(et_li 类),则该列表项的内容必须在关闭下拉列表之前填充文本框。

注意:所有 lis 都是动态生成的。我不知道这是否有区别。

此代码将 li 内容放入文本框中,但不会关闭下拉菜单。

$( ".et_email" ).focusout(function() {
    $(".typeahead_list").on("click", "li", function() {
        $(".et_email").val($(this).text());});  
    //$(".typeahead_list").hide();
});

此代码关闭下拉菜单,但不会将 li 的内容放入文本框中。

$( ".et_email" ).focusout(function() {
    $(".typeahead_list").on("click", "li", function() {
        $(".et_email").val($(this).text());});  
    $(".typeahead_list").hide();
});

关于如何解决这个问题的任何想法?冲突从何而来?

更新:

Alex Cassady 提出了以下修复建议:

$(".typeahead_list").on("click", "li", function() {
    $(".et_email").val($(this).text()); // copy value
    $(".typeahead_list").hide(); // then hide
}); 

感谢您的帮助。我之前研究过类似的解决方案。但是,我遇到了一个问题,因为每当电子邮件箱因任何原因失去焦点时,我都需要关闭下拉菜单......同时仍然响应 li 点击。在此示例中,下拉菜单仅在有人单击 li 时关闭。

但是,如果我尝试在 $(document).ready() 中为 $( ".et_email" ).focusout() 添加另一个处理程序,它将完全使该函数的效果无效。就像 $( ".et_email" ).focusout() 和 $(".typeahead_list").on("click", "li", function(){}) 不能一起生活在同一个宇宙中。有某种冲突。

基本上,我需要实现的规则是:当 et_email 因任何原因失去焦点时,始终关闭下拉菜单......但如果由于使用 typeahead_list div 的 li 单击而失去焦点,则使用内容填充文本框关闭下拉列表之前的那个 li。

【问题讨论】:

  • 控制台没有错误?这个函数在$(document).ready 函数中吗?
  • 不要嵌套处理程序...
  • @odedta - 是的,它在 $(document).ready 中。

标签: javascript jquery css twitter-bootstrap dom


【解决方案1】:

您正在将点击侦听器绑定到一个元素,该元素将立即隐藏,因此无法点击!如果您评论 hide() 行,它起作用的原因是它可以被点击。

如果你只是想要隐藏之前的文本:

$( ".et_email" ).focusout(function() {
    $(".et_email").val($(".typeahead_list").text());  
    $(".typeahead_list").hide();
});

编辑:

好的,我想我对你想要做的事情有了更好的理解。这不是一个干净的解决方案,但可以完成这项工作。

有一个全局变量'focusLost'或任何东西,它会在每次.et_email失去焦点时设置为true,并在一秒钟内设置为false。在.typeahead_list点击监听器中,我们检查focusLost是否为真。

var focusLost = false;

$('.typeahead_list').on('click', function () {
    if (focusLost) {
        $('.et_email').val(($(this).text()));
        $(this).hide();
    }
});

$('.et_email').focusout(function () {
    focusLost = true;
    setTimeout(function () {
        $('.typeahead_list').hide();
        focusLost = false;
    }, 1000);
});

jsfiddle DEMO

【讨论】:

  • 谢谢武士。不幸的是,每当 et_email 失去焦点时,它就会用 typeahead_list 的内容填充文本框。只有在单击 typeahead_list 中的 li 元素之一导致焦点丢失时才会发生这种情况。所有其他失去焦点的原因应该简单地关闭下拉列表而不改变文本框的内容。
  • 查看编辑,还添加了一个演示,对下拉菜单不太确定,但您明白了。
  • 感谢您的帮助。
【解决方案2】:

正如 A. Wolff 所说,不要嵌套处理程序。 focusout 事件绑定到所有 .et_email,但在触发 focusout 事件之前,click 事件不会绑定到 .typeahead_list。

.typeahead_list 在值可以更改之前被隐藏。 Focusout 与在 .et_email 外部单击相同,并且首先调用它。 完全删除 focusout 事件处理程序应该可以解决问题。

$(".typeahead_list").on("click", "li", function() {
    $(".et_email").val($(this).text()); // copy value
    $(".typeahead_list").hide(); // then hide
}); 

编辑:您也可以尝试在 $.hide() 的回调函数中复制值

$(".typeahead_list").on("click", "li", function() {

    $(".typeahead_list").hide( function() {
        $(".et_email").val($(this).text()); // copy value
    }); // then hide
});

【讨论】:

  • 感谢您的帮助。我之前研究过类似的解决方案。但是,我遇到了一个问题,因为每当电子邮件箱因任何原因失去焦点时,我都需要关闭下拉菜单......同时仍然响应 li 点击。在此示例中,仅当有人单击 li 时下拉菜单才会关闭。请参阅我上面的更新中的详细信息。
猜你喜欢
  • 2012-03-06
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多