Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
515 views
in Technique[技术] by (71.8m points)

jquery - Sync vote button with backend vote function

I have a vote button which should change color and count immediately in my view. The backend function triggered through the button should process in the backend so the user does not recognize it. The problem is if I change the color of my button in my view with jquery this runs out of sync with the backend function if a user presses the button very fast. So I wanna know how to handle this? If I do it with the ajax response it takes to long.. and this is not a good user experience. I hope you guys understand what I mean?

<a data-id="{{ $article->id }}" class="vote {{ Auth::check() && Auth::user()->votedFor($article) ? 'active' : '' }}"></a>

 <div class="points">{{ $article->votes->count() }}</div>

The script I wanna use to change color of button and count in my view

      $(document).on('click', '.vote', function() {
    var $counter = $(this).parent().find('.points');
    $(this).toggleClass('active');
    if($(this).hasClass('active')) {
      $counter.html(parseInt($counter.text(), 10) + 1);
    } else {
      $counter.html(parseInt($counter.text(), 10) - 1);
    }
    var $button = $(this);
    $button.addClass('vote-live');
    var id = $button.data('id');
    var token = $('meta[name="csrf-token"]').attr('content');
    $.ajax({

        type: 'POST',
        url: "{!! URL::to('article/vote/') !!}/" + id,
        dataType: 'JSON',
        data: {
            "_method": 'POST',
            "_token": token,
            "id": id,
        },
        success: function(data) {
            $counter.html(data.count);
            $button.removeClass('vote-live');
            // var color = data.voted ? 'transparent transparent #a53031 transparent' : 'transparent transparent #a53031 transparent';
            // $button.css('border-color', color);
            console.log('success');
            console.log(data);
        },
        error: function(xhr) {
            $button.removeClass('vote-live');
            if (xhr.status == 401) {
                window.location.href = "{!! URL::to('login') !!}";
            } else if (xhr.status == 403) {
                window.location.href = "{!! URL::to('email/verify') !!}";
            }
        },
    });
});

Did it like so but dont know if thats the way to go? Looks a little bit unprofessional but I have no idea how its normally done...

    $(this).toggleClass('active');
      if($(this).hasClass('active')) {
        $counter.html(1);
      } else {
        $counter.html(0);
      }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The solution here is disabling the button when the service is not completed yet. To do it, you just add class name .is-sending when user click the button, this is CSS:

.is-sending {
  pointer-events: none; // prevents the pointer event, so they cannot click
  cursor: default;
  opacity: 0.6; 
}

Then in success you remove that class name. I highly recommend you should use the button element instead of a element, and in this case you can use disabled attribute instead of .is-sending class name.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...