我创建了一个非常简单的jQuery“下拉列表”,它由两个div元素组成。单击第一个div时,将显示第二个div。现在我希望第二个div再次关闭,当我点击div之外。但我不能(并且实际上不想,如果没有必要)使用这样的文档或身体事件监听器:
$('#div2').click(function(e) {
doSomething();
e.stopPropagation();
});
$(document).click(function() {
$("#div2").hide();
});
原因:我在页面上有其他使用e.stopPropagation();
的元素,如果用户在打开下拉列表后点击了这些元素,则不会再次关闭。
我发现这个插件,jALDropdown,即使我点击e.stopPropagation();
,甚至点击页面或浏览器之外的某个地方,以某种方式处理关闭下拉列表,它似乎没有使用任何文档/正文-event-listener:http://india.assigninfo.com/assignlabs/jaldropdown
可悲的是,它不能与Opera合作,所以我无法使用它。而且我没有找到未最小化的源代码版本,因此我无法找到它的工作原理。
您是否有任何想法如何实现此行为,以便在没有文档/正文事件监听器的情况下单击元素,页面甚至浏览器外部时,下拉关闭(元素被隐藏)?谢谢!
答案 0 :(得分:1)
为什么不保留$(document).click()函数来隐藏你的除法,然后将这个函数添加到你的代码中并调用它而不是event.stopPropagation():
function stopPropAndCloseDiv2(event) {
$('#div2').hide();
event.stopPropagation();
};
我测试了它,似乎它可以正常工作。你只需记得使用它。
更新:
这对我嗤之以鼻,我在这个知道的网站上找到了另一个答案。这是链接:
add code to a function programatically with JS
我尝试了这种方法,似乎有效:http://jsfiddle.net/kXkFS/8/
这是代码(测试页面标记中有两个按钮):
jQuery.Event.prototype.stopPropagation = (function() {
var cached_function = jQuery.Event.prototype.stopPropagation;
return function() {
if ( this.type == "click") {
// Your logic here.
console.log("I am a modified version of event.stopPropagation()!");
}
cached_function.apply(this, arguments); // use .apply() to call it.
};
}());
$(document).click( function() { console.log("The document caught the event, too."); });
$('#clicker').click( function() { console.log("I'm going to let this event bubble."); });
$('#anotherClicker').click( function(event) { event.stopPropagation(); });
Spoiler:当您单击“clicker”按钮时,文档也会记录到控制台。单击“anotherClicker”按钮时,自定义event.stopPropagation()函数将记录到控制台,文档不会登录到控制台。现在,您可以将单击事件处理程序添加到文档中。
有一点:这可能会增加一些开销,但只有当你经常调用stopPropagation()时才会这样做。
如果有人想要像这样强调与jQuery对象搞砸的智慧,请这样做。我想知道,但我看不出像这样一个无害的变化会在将来炸毁网页。
答案 1 :(得分:0)
//generic drop-down menu
//NOTE: only pass a menu object if there are multiple menus per toggle object
var dropDown = function( toggle, menus )
{
toggle.click( function( e ) {
e.preventDefault();
//NOTE: container is assuming that the next sibling is the dropdown.
//change container to suit your needs
var container = $( this ).next();
if( menus !== undefined && !container.is( ':visible' ) ){ menus.hide(); }
if( !container.is( ':visible' ) )
{
container.fadeIn( 'fast' );
}
else
{
container.fadeOut( 'fast' );
}
});
}
//close stuff when the window is clicked
var window_click = function( obj )
{
$( window ).click( function( e ) {
if( obj.is( ':visible' ) )
{
obj.fadeOut( 250 );
}
});
}
//override the window_click function when needed
var stop_prop = function( obj )
{
obj.click( function( e ) {
e.stopPropagation();
});
}
现在,只需在任何地方使用它们:
var toggle = $( '#myToggle' );
var menu = $( '#myMenu' );
dropDown( toggle, menu );
window_click( menu );
stop_prop( toggle );
stop_prop( menu );
对于我的下拉标记,我几乎总是使用这个模型:
<span class='toggle_name'></span>
<ul class='menu_name' style='display:none;'>
<li>cool man</li>
</ul>
要绕过分散的stopPropagation(),您还可以创建一个手动关闭所有菜单类的小函数。超级简单:
var menus = {
//add any dropdown menu ids or classes here
}
//run this method on any conflicting stopProp clicks
var closeMenus = function()
{
for( var key in menus )
{
if( menus.hasOwnProperty( key ) )
{
menus[key].hide();
}
}
}