繁体   English   中英

$(event.target).closest()。隐藏div的长度并不总是有效。任何替代品?

[英]$(event.target).closest().length to hide div doesn't always work. Any alternatives?

我使用$(event.target).closest("#divID").length来隐藏div当用户点击它时,但是如果div是可见的,我点击日期(datepicker)它赢了' t隐藏div

此外,如果我点击<select>有时它隐藏它有时它不会。

有什么更好的解决方案可以在点击其他内容时隐藏div吗?

我的实施错了吗?

ps: #log_in是登录按钮, #log_in_form是我要在外部点击时隐藏的form#log_in_container是包含#log_in#log_in_form的div

更新:我刚注意到在Windows 10和Linux ubuntu 16.04上的消失是不一样的。 在使用谷歌浏览器使用谷歌浏览器的PC上,表格在第一次点击时消失了(这是理想的功能),但如果我选择日期,它仍然不会消失。 虽然在谷歌Chrome上的Linux ubuntu 16.04上,它就像我上面描述的那样(在选择日期时不会消失,并且在你选择的第一次点击时也不会消失)

示例基于Andrei对代码段的回答

 $(document).on('click', function(e){ if($(e.target).closest('#log_in').is('#log_in')) { $('#log_in_form').fadeIn(); } else if(!$(e.target).closest('#log_in_container').is('#log_in_container')) { $('#log_in_form').fadeOut(); } }) 
 #log_in_container{ display:inline-block; width:122px; height:58px; margin-left:60px; background-color:gray; } #log_in{ display:block; width:120px; height:28px; text-align: center; border: 1px solid red; font-size:16px; background-color:yellow; vertical-align: top; } #log_in_form{ display:none; position:absolute; width:120px; height:28px; text-align: center; background-color: green; border: 1px solid blue; } .type{ display:inline-block; width:120px; height:30px; text-align: center; border: 1px solid red; font-size:16px; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- ~~~~~~~~~~~~~~~Date picker ~~~~~~~~~~~~~~~ --> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#datepicker" ).datepicker(); }); </script> <title></title> </head> <body> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select hero</p></option> <option value="0">Spiderman</option> <option value="1">Iron man</option> <option value="2">Deadpool</option> </select> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select food</p></option> <option value="0">Kebab</option> <option value="1">Mousaka</option> <option value="2">Noodles</option> </select> <div id="log_in_container"> <div id="log_in">Log_In_button</div> <div id ="log_in_form">login_form</div> </div> <div id="datepicker"></div> </body> </html> 

在上面的代码片段中,如果单击Log_in_button,则会显示Log_in_form。 如果然后你点击它不会消失的日期,然后点击一个选择Log_in_form仍然不会消失,之后点击下一步选择Log_in_form仍然可见。 我想这样做,以便它在这些场合消失(如选择弹出窗口)。 这可能吗?

jQuery仅适用于事件冒泡(事件从目标元素开始并处理 DOM树,引发单击事件直到它到达顶级document )。 正如您在ui-datepicker看到的那样,潜在的问题是元素可以通过使用event.stopPropagation()取消冒泡,并且document永远不会得到它。

相反,你需要使用原始的Javascript事件捕获代替,其中顶层元素捕获事件发生并传递下来的DOM树。

W3C网站图表很好地解释了捕获和气泡流,并查看了这个问题以获取更多详细信息和跨浏览器实现。

您的代码所需的更改很少,您只需使用document.addEventListener而不是$(document).on

 document.addEventListener("click", function(e){ if($(e.target).closest('#log_in').is('#log_in')) { $('#log_in_form').fadeIn(); } else if(!$(e.target).closest('#log_in_container').is('#log_in_container')) { $('#log_in_form').fadeOut(); } }, true); 
 #log_in_container{ display:inline-block; width:122px; height:58px; margin-left:60px; background-color:gray; } #log_in{ display:block; width:120px; height:28px; text-align: center; border: 1px solid red; font-size:16px; background-color:yellow; vertical-align: top; } #log_in_form{ display:none; position:absolute; width:120px; height:28px; text-align: center; background-color: green; border: 1px solid blue; } .type{ display:inline-block; width:120px; height:30px; text-align: center; border: 1px solid red; font-size:16px; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- ~~~~~~~~~~~~~~~Date picker ~~~~~~~~~~~~~~~ --> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#datepicker" ).datepicker(); }); </script> <title></title> </head> <body> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select hero</p></option> <option value="0">Spiderman</option> <option value="1">Iron man</option> <option value="2">Deadpool</option> </select> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select food</p></option> <option value="0">Kebab</option> <option value="1">Mousaka</option> <option value="2">Noodles</option> </select> <div id="log_in_container"> <div id="log_in">Log_In_button</div> <div id ="log_in_form">login_form</div> </div> <div id="datepicker"></div> </body> </html> 

正如您之前提到的,最初的<select>在Windows上的Chrome中有效,但在Linux上却无效。 浏览器通常会将表单控件的呈现交给操作系统以实现视觉一致性,但这会导致行为不一致。 <select> s可能是基本表单控件中最不一致的,因为它们增加了复杂性。 这个问题证明了这个问题,特别是:

Linux上的Chrome 19:首先鼠标单击展开选项[单击事件未触发],然后单击仍然存在的选项或选项,触发单击事件。

由于这是一个你无法控制的浏览器行为,我认为没有办法解决它 - 你只能处理它触发的事件。 如果浏览器未触发该事件,则无法对其做出反应。

您只需使用mouseup事件而不是click在日期点击时使用。

 $(document).on('mouseup', function(e){ if($(e.target).closest('#log_in').is('#log_in')) { $('#log_in_form').fadeIn(); } else if(!$(e.target).closest('#log_in_container').is('#log_in_container')) { $('#log_in_form').fadeOut(); } }) 
 #log_in_container{ display:inline-block; width:122px; height:58px; margin-left:60px; background-color:gray; } #log_in{ display:block; width:120px; height:28px; text-align: center; border: 1px solid red; font-size:16px; background-color:yellow; vertical-align: top; } #log_in_form{ display:none; position:absolute; width:120px; height:28px; text-align: center; background-color: green; border: 1px solid blue; } .type{ display:inline-block; width:120px; height:30px; text-align: center; border: 1px solid red; font-size:16px; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- ~~~~~~~~~~~~~~~Date picker ~~~~~~~~~~~~~~~ --> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#datepicker" ).datepicker(); }); </script> <title></title> </head> <body> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select hero</p></option> <option value="0">Spiderman</option> <option value="1">Iron man</option> <option value="2">Deadpool</option> </select> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select food</p></option> <option value="0">Kebab</option> <option value="1">Mousaka</option> <option value="2">Noodles</option> </select> <div id="log_in_container"> <div id="log_in">Log_In_button</div> <div id ="log_in_form">login_form</div> </div> <div id="datepicker"></div> </body> </html> 

除了dateoicker <td>之外,您的代码正在运行。 这真的很奇怪

但是我们仍然可以使用jQuery ui datepicker中的onSelect方法来破解它。

 $(document).on('click', function(e){ if($(e.target).closest('#log_in').is('#log_in')) { $('#log_in_form').fadeIn(); } else if(!$(e.target).closest('#log_in_container').is('#log_in_container')) { $('#log_in_form').fadeOut(); } }) 
 #log_in_container{ display:inline-block; width:122px; height:58px; margin-left:60px; background-color:gray; } #log_in{ display:block; width:120px; height:28px; text-align: center; border: 1px solid red; font-size:16px; background-color:yellow; vertical-align: top; } #log_in_form{ display:none; position:absolute; width:120px; height:28px; text-align: center; background-color: green; border: 1px solid blue; } .type{ display:inline-block; width:120px; height:30px; text-align: center; border: 1px solid red; font-size:16px; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- ~~~~~~~~~~~~~~~Date picker ~~~~~~~~~~~~~~~ --> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#datepicker" ).datepicker({ onSelect: function(i, e){ $('#log_in_form').fadeOut(); } }); }); </script> <title></title> </head> <body> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select hero</p></option> <option value="0">Spiderman</option> <option value="1">Iron man</option> <option value="2">Deadpool</option> </select> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select food</p></option> <option value="0">Kebab</option> <option value="1">Mousaka</option> <option value="2">Noodles</option> </select> <div id="log_in_container"> <div id="log_in">Log_In_button</div> <div id ="log_in_form">login_form</div> </div> <div id="datepicker"></div> </body> </html> 

我有一个建议是使用事件mousedown而不是click并检查点击是否发生在日志包装中这样

$(e.target).parents().has($('#log_in_container')).length

准备好的整个文件看起来像这样

$(document).on('mousedown', function(e){
    if($(e.target).closest('#log_in').is('#log_in'))
    {
      $('#log_in_form').fadeIn();
    }
    else if($(e.target).parents().has($('#log_in_container')).length)
    {
      $('#log_in_form').fadeOut();
    }
})

你为什么不使用onSelect的事件datepicker ,并触发你的点击bounddocument手动,因为它似乎并没有当你点击里面的日期被触发datepicker ,没有必要改变对任何事件或者在onSelect编写一个单独的逻辑,只需在.on('click')添加更多逻辑并触发它只需添加2行代码并保持原样。

您只需要更改datepicker初始化,如下所示

$("#datepicker").datepicker({
    onSelect: function (date, obj) {
        $(document).trigger('click')
    }
});

请参阅下面的演示

 $(document).on('click', function(e) { if ($(e.target).closest('#log_in').is('#log_in')) { $('#log_in_form').fadeIn(); } else if (!$(e.target).closest('#log_in_container').is('#log_in_container')) { $('#log_in_form').fadeOut(); } }) 
 #log_in_container { display: inline-block; width: 122px; height: 58px; margin-left: 60px; background-color: gray; } #log_in { display: block; width: 120px; height: 28px; text-align: center; border: 1px solid red; font-size: 16px; background-color: yellow; vertical-align: top; } #log_in_form { display: none; position: absolute; width: 120px; height: 28px; text-align: center; background-color: green; border: 1px solid blue; } .type { display: inline-block; width: 120px; height: 30px; text-align: center; border: 1px solid red; font-size: 16px; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- ~~~~~~~~~~~~~~~Date picker ~~~~~~~~~~~~~~~ --> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $(function() { $("#datepicker").datepicker({ onSelect: function(date, obj) { $(document).trigger('click') } }); }); </script> <title></title> </head> <body> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select hero</p></option> <option value="0">Spiderman</option> <option value="1">Iron man</option> <option value="2">Deadpool</option> </select> <select class="type"> <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select food</p></option> <option value="0">Kebab</option> <option value="1">Mousaka</option> <option value="2">Noodles</option> </select> <div id="log_in_container"> <div id="log_in">Log_In_button</div> <div id="log_in_form">login_form</div> </div> <div id="datepicker"></div> </body> </html> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM