简体   繁体   中英

ajax jquery and click event


I have several buttons that have the same class 'unfollow'.
When the user clicks on one of the buttons it's triggering ajax request and changing the class to 'follow', and adding a click listener to the class.
When the user clicks on the 'follow' button it's triggering a new ajax request and changing the class to 'unfollow'.
Now the result is when the user clicks on the 'unfollow' link everything goes well, but when the user clicks on the 'follow' button it's triggering 2 ajax requests, 1 of the 'unfollow' and 1 of the 'follow'.

Resolved

The new code:
the promises simulate the ajax requests

$('.btn').click(function(event) {
  var $self = $(this);
  var screenName = $self.parent().prev().children().children('p').text().substring(1);

  if ($self.hasClass('unfollow')) {
    var unfollowReq = new Promise(function(resolve, reject) {
      $self.removeClass('unfollow').addClass('follow');
      $self.text('Follow');
      console.log('Unfollow');
      resolve();
    });
  } else if ($self.hasClass('follow')){
    var unfollowReq = new Promise(function(resolve, reject) {
      $self.removeClass('follow').addClass('unfollow');
      $self.text('Unfollow');
      console.log('Follow');
      resolve();
    });
  }
});

Updated JSFiddle

Regards,
Liad.

You must remove the follow event listener after the follow click.

Use unbind() for this.

https://api.jquery.com/unbind/

this is a way to toggle them using data-...

<button type="button" data-id="$id" data-action="follow" class="btn btn-primary btn-request">Follow</button>

$('.btn-request').click(function(e){
  var btn = $(this);
  var id = btn.data('id');
  var action = btn.data('action').toLowerCase();
  $(url, { id: id, action: (action == "follow" ? "unfollow" : "follow") }, funciton(result) {
      btn.data('action', (action == "follow" ? "Unfollow" : "Follow"));
      btn.html(btn.data('action'));
  });
});

or you can use off() or unbind() functions

For something like this, event delegation is your best friend.

You can permanently delegate the two behaviours, follow and unfollow, to containing element(s). Thus, the buttons' behaviour, like their appearance, can be determined solely by the presence/absence of classNames - "follow" or "unfollow" in this case. There's no need to attach/detach event handlers.

jQuery's .on() provides all the necessary fnctionality.

$(document).on('click', '.unfollow', function(event) {
    $self = $(this).removeClass('unfollow');
    // At this point, with neither class, 'follow' nor 'unfollow', the button is effectively disabled.
    $ajax(...).then(function() {
        // With assurance that the server-side state is at "unfollow", give the button "follow" appearance and behaviour.
        $self.addClass('follow').text('Follow');
    }, function(err) {
        // Hmm state is indeterminate.
        // Probably safer to assume that the ajax failed completely, therefore revert to "unfollow".
        $self.addClass('unfollow').text('Unfollow');
    });
}).on('click', '.follow', function() {
    $self = $(this).removeClass('follow');
    // At this point, with neither class, 'follow' nor 'unfollow', the button is effectively disabled.
    $ajax(...).then(function() {
        // With assurance that the server-side state is at "follow", give the button "unfollow" appearance and behaviour.
        $self.addClass('unfollow').text('Unfollow');
    }, function(err) {
        // Hmm state is indeterminate.
        // Probably safer to assume that the ajax failed completely, therefore revert to "follow".
        $self.addClass('follow').text('Follow');
    });
});

In practice, you would probably delegate to something other than document .

Promises appear to be completely irrelevant and are omitted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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