Show and Hide handlers are applied multiple times on each click
This is my html code:
<span id="username_{{ member.id }}" onclick="showMembershipData('{{ member.id }}');">{{ member.user.username }}</span>
and this is my jQuery code
function showMembershipData(id)
{
$("#memberInfo_"+id).slideDown();
$("#username_"+id).click(function(){
hideMembershipData(id);
});
}
function hideMembershipData(id) {
$("#memberInfo_" + id).slideUp();
$("#username_" + id).click(function() {
showMembershipData(id);
});
}
开发者_StackOverflow社区I want the user name to be clickable and when clicked open the "more information" pane, or close it if it is opened. What happens now is:
- username clicked for 1 time: pane opens.
- Clicked 2nd time: pane closes. Up to here is fine...
- clicked 3rd time pane opens and closes 2 times in a row (i.e. 4 operations: open, close, open, close)
and so on... Why? What am I doing wrong?
You are assigning handler inside each handler, and you only need to assign handler once or even consider using event delegation $.on(event, selector, handler)
if you are adding and removing items.
consider code below, and remove handlers from markup:
add class
username
to elements with idusername_xxx
add class
memberInfo
to elements with idmemeberInfo_xxx
add
data-id
attribute to elements with idusername_xxx
So markup going to look like:
<span class="username" data-id"{{ member.id }}">{{ member.user.username }}</span>
And the script:
$('body').on('click', '.username', function(e) {
var id = $(this).data('id')
$('#memberInfo_'+id).toggle()
})
The problem with your code is that even handlers are been attached multiple times. Basically with jQuery if you do something like
$("#element").click(functionName);
$("#element").click(functionName);
$("#element").click(functionName);
Then clicking the element once will fire functionName thrice! You need to refactor your code a bit to make sure that the event handlers are added and removed appropriately. Try this
function showMembershipData(id)
{
$("#memberInfo_"+id).slideDown();
$("#username_"+id).unbind("click").bind("click",(function(){
hideMembershipData(id);
});
}
function hideMembershipData(id) {
$("#memberInfo_" + id).slideUp();
$("#username_" + id).unbind("click").bind("click",(function() {
showMembershipData(id);
});
}
let's change the code a little bit, shall we
<span
id="username_{{ member.id }}"
class="member"
data-memberid="{{ member.id }}">{{ member.user.username }}</span>
on the jQuery side
$(".member").toggle(
function() { // click - show
var id = $(this).attr("data-memberid");
$("#memberInfo_" + id).stop().slideDown();
},
function() { // click again - hide
var id = $(this).attr("data-memberid");
$("#memberInfo_" + id).stop().slideUp();
});
easy :)
You can make life a whole lot easier by using jQuery's slideToggle()
method - try the following:
function showMembershipData(id) { $("#memberInfo_"+id).slideToggle(); }
This will toggle the #memberInfo + id
(whatever the ID is) when the link is clicked. Can I suggest using jQuery's click()
function? (needs a class added to the username span
):
$("#username_span").click(function() { $("#memberInfo_"+id).slideToggle(); });
Don't forget to add it to your $(document).ready()
bit or whatever. Once you've done that, you can remove the onClick
from the span.
James
Agree with the guys above...you keep registering the events. If all you're doing is opening and closing one:
$('#clickme').click(function() {
$('#book').slideToggle('slow', function() {
// Animation complete.
});
});
http://api.jquery.com/slideToggle/
Problem here is that you add an event handler each time showMembershipData
gets called.
You should make sure only one event handler gets assigned.
It is happenign 2 times in a row because each time you call those functions they bind a click function which fires.
try
$("#username_"+id).click(function(){
var $showHideElement =$("#memberInfo_"+id);
if ($showHideElementis(':visible'){
$showHideElement.slideUp();
}else{
$showHideElement.slideDown();
}
})
精彩评论