使用AJAX的投票/取消投票系统

使用AJAX的投票/取消投票系统,ajax,django,Ajax,Django,我使用AJAX在Django上实现了一个投票/取消投票系统,如下所示: $('.votable').click(function(){ var element = $(this), postid = element.attr("data-postid"); if (element.hasClass('voted')) { // Unvoting $.get('/unvote/', {post_id: postid}, functi

我使用AJAX在Django上实现了一个投票/取消投票系统,如下所示:

$('.votable').click(function(){
    var element = $(this),
        postid = element.attr("data-postid");

    if (element.hasClass('voted')) {
        // Unvoting
        $.get('/unvote/', {post_id: postid}, function(data) { //Send post_id to unvote view
            $('#points' + postid).html(data); // Data changed element
            $('#' + postid).removeClass('voted');
        }); 
    } else {
        // Voting
        $.get('/vote/', {post_id: postid}, function(data) { //Send post_id to vote view
            $('#points' + postid).html(data); // Data changed element
            $('#' + postid).addClass('voted');
        });
    }

视图.py

@login_required
def vote(request):
    post_id = None
    if request.method == 'GET':
        post_id = request.GET['post_id']

    if post_id:
        post = Post.objects.get(id=int(post_id))
        current_user = request.user.id

    try:
        voted = Vote.objects.get(post=post, user=current_user)
    except Vote.DoesNotExist:
        voted = None

    # Voting code

    if not voted:
        Vote.objects.get_or_create(post=post, user=request.user)
        post.points = post.vote_set.all().count()
        post.save()
        print("voted!")

    return HttpResponse(post.points)

@login_required
def unvote(request):
    post_id = None
    if request.method == 'GET':
        post_id = request.GET['post_id']

    if post_id:
        post = Post.objects.get(id=int(post_id))
        current_user = request.user.id

    try:
        voted = Vote.objects.get(post=post, user=current_user)
    except Vote.DoesNotExist:
        voted = None

    # Voting code

    if voted:
        Vote.objects.filter(post=post, user=request.user).delete()
        post.points = post.vote_set.all().count()
        post.save()
        print("unvoted!")

    return HttpResponse(post.points)
main.js

// Voting
$('.vote').click(function(){
    var postid;
    postid = $(this).attr("data-postid");
    $.get('/vote/', {post_id: postid}, function(data){ //Send post_id to vote view
        $('#points' + postid).html(data); // Data changed element
        $('#' + postid).attr('class', 'voted');
    });
});

// Unvoting
$('.voted').click(function(){
    var postid;
    postid = $(this).attr("data-postid");
    $.get('/unvote/', {post_id: postid}, function(data){ //Send post_id to unvote view
        $('#points' + postid).html(data); // Data changed element
        $('#' + postid).attr('class', 'vote');
    });
});

投票工作正常,但我必须刷新页面以取消注释。以及取消投票,然后再次投票。这里发生了什么?

问题是,当您加载页面时,只有一个元素具有
投票
投票
类。您应该添加一个类,比如说
votable
,然后执行如下操作:

$('.votable').click(function(){
    var element = $(this),
        postid = element.attr("data-postid");

    if (element.hasClass('voted')) {
        // Unvoting
        $.get('/unvote/', {post_id: postid}, function(data) { //Send post_id to unvote view
            $('#points' + postid).html(data); // Data changed element
            $('#' + postid).removeClass('voted');
        }); 
    } else {
        // Voting
        $.get('/vote/', {post_id: postid}, function(data) { //Send post_id to vote view
            $('#points' + postid).html(data); // Data changed element
            $('#' + postid).addClass('voted');
        });
    }
click事件上的click()函数绑定是一个直接绑定,它只会将单击事件处理程序附加到已经存在的元素,它既不会绑定到将来创建的元素,也不会绑定到通过动态添加或删除的属性(在本例中为类)选择的元素

以下.on()方法将在整个动态更改过程中起作用

$(document).on('click','.vote', function() {
    //Do Stuff
});
一般来说,通过一个特定的类访问一个元素,您希望通过代码动态地添加和删除这个类,这是一个值得商榷的做法。您应该通过id、名称或不添加或删除的类来访问元素,这样可以简化整体结构

如果您通过
$(document).on('click','yourId',function(){})访问元素它将清除您可能遇到的一些问题