问题
I'm trying to create a dropdown menu which can be opened and closed with a Toggle button and it can be closed by clicking anywhere on the document itself as well.
When a person clicks on the Toggle button, the menu opens properly. If a visitor then clicks anywhere else on the document, the menu closes but it takes 2 clicks to activate the Toggle function of that button again. I'd like to reduce that to 1 click again, of course.
Check out http://jsfiddle.net/MEweN/3/ for this issue. Can anyone help me out please?
回答1:
Toggle saves it's state on the object you call it on. Each time you call Toggle, it alternates between function 1 and function 2. It knows nothing else about your app. It just alternates between the two functions you pass it each time you call it.
When you reset the state of the popup without using Toggle, it gets out of sync as it now has no idea that you want to go back to the first state. So, when you click again, it executes the second function when you want it to execute the first function.
The best way to solve this problem is to use something smarter than Toggle. You need to either detect whether the popup is open and act accordingly or store some state on whether it's open or not. You can't use Toggle because it isn't smart enough for your application.
In working with your actual code, I also found that handling the mouseup event in the document is not very compatible with handling the click event in the object. The issue is that mouseup comes before click so you would get both events in sequence and you wouldn't get the effect you want. When I changed to a click in the document, it worked a lot easier like this:
$("#general_show").click(function () {
var $this = $(this);
if ($this.hasClass('selected')) {
$this.removeClass('selected').parent().next().hide();
} else {
$this.addClass('selected').parent().next().show();
}
return(false);
});
$(document).click(function (e) {
if ($('#general_info').is(':visible') &&
$(e.target).parents('#general_info').length === 0) {
$('#general_show').removeClass('selected').parent().next().hide();
return(false);
}
});
Working example: http://jsfiddle.net/jfriend00/KTNAq/
回答2:
$("#general_show").click(function () {
if( $(this).is('.selected') ){
$(this).removeClass().parent().next().hide()
}else{
$(this).addClass('selected').parent().next().show()
}
});
$(document).mouseup(function (e) {
if (
$('#general_show').is('.selected')
&& $(e.target).parents('#general_info').length === 0
&& $(e.target).attr('id')!== "general_show"
) {
$('#general_show').click()
}
});
回答3:
$("#general_show").click(function () {
if ( $('#general_info').is(':visible') ){
// Hiding informations
$(this).removeClass('selected').parent().next().hide(); // try to always pass argument to removeClass, which class you want to remove
} else {
// Showin informations
$(this).addClass('selected').parent().next().show();
}});
$(document).mouseup(function (e) {
// We don't want to use this function when clicked on button
if (e.target.id == 'general_show') return;
if ( $('#general_info').is(':visible') ){
$('#general_show').removeClass().parent().next().hide();
}
});
JSFiddle link: http://jsfiddle.net/MEweN/5/
来源:https://stackoverflow.com/questions/8702166/jquery-toggle-function-conflicts-with-mouseup