开发者

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 id username_xxx

  • add class memberInfo to elements with id memeberInfo_xxx

  • add data-id attribute to elements with id username_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();
  }
})
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜