简体   繁体   中英

jQuery and AJAX on click only works once

I am trying to make a like/unlike button with jQuery and Ajax. Problem is that when I like something I can't unlike it until I refresh the page, and if I unlike something, I can't like it again until I refresh the page.

Here's my PHP/html:

<?php
require('con.php');
session_start();

if (!empty($_POST)) {
    $un = $_SESSION['un'];
    $op = $_POST['op'];
    $pid = $_POST['pid'];
    if ($op == "like") {
        mysqli_query($con, "INSERT INTO likes (pid, uid, date_liked, username) VALUES ('$pid', '".$_SESSION['id']."', now(), '".$_SESSION['un']."')") or die(mysqli_error($con));
        echo 1;
        exit;
    } elseif ($op == "unlike") {
        mysqli_query($con, "DELETE FROM likes WHERE pid = '$pid' AND username = '$un'");
        echo 1;
        exit();
    }
}    
?>
<!DOCTYPE html>
<html>
<head>
    <title>Test 2 Test</title>
    <script src="//code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<?
$sql = mysqli_query($con, "SELECT * FROM posts") or die(mysqli_error($con));
//get all the posts from the posts table
while ($r = mysqli_fetch_assoc($sql)) {
    $b = $r['body'];
    $u = $r['uid'];
    $pid = $r['pid'];

    $s = mysqli_query($con,"SELECT username, pid FROM likes WHERE pid = '$pid' ") or die(mysqli_error($con));
    //get all the likes that correspond with the post id from the likes table
    $n = mysqli_num_rows($s);
    //the number of likes
    $r = mysqli_fetch_assoc($s);
    $user = $r['username'];
    if ($user !== $_SESSION['un']) {
    //if the user hasn't liked the post yet
        echo "<div>$b</div>";
        echo "<input type = 'button' value = '$n' id = 'like_$pid' class='$pid'>";
        //the like button
        echo "<br><br>"; ?>
        <!-- jQuery Script here -->

    <?
    } else {
    //the user has liked the post
        echo "<div>$b</div>";
        echo "<input type = 'button' value = '$n' id = 'unlike_$pid' class='$pid'>";
        //the unlike button
        echo "<br><br>"; ?>
        <!-- More jQuery -->
   <? 
    }
}
?>

My jQuery:

$(document).ready(function() {
    $('#like_' + <? echo $pid; ?>).click(function() {
        var val = parseInt($(this).val(), 10);
        var pid = $("." + <? echo $pid; ?>).val();
        //create a variable with the num of likes
        $.post("test2test.php", {op: "like", pid: pid}, function(data) {
            val = val + 1;
            $('#like_' + <? echo $pid; ?>).val(val);
            $("#like_" + <? echo $pid; ?>).attr("id", "unlike_<? echo $pid; ?>");
        });
     });
     $('#unlike_' + <? echo $pid; ?>).click(function() {
        var val = parseInt($(this).val(), 10);
        var pid = $("." + <? echo $pid; ?>).val();
        $.post("test2test.php", {op: "unlike", pid: pid}, function(data) {
            val = val - 1;
            $("#unlike_" + <? echo $pid; ?>).val(val);
            $('#unlike_' + <? echo $pid; ?>).attr("id", "like_<? echo $pid; ?>");
        });
    });
});

I put this code wherever it said <!--jQuery Script here--> or <!--More jQuery-->

All of this is on one page. I'm not getting any PHP of javascript errors, so I don't know what's up.

Please help me.

PS: I am a beginner in jQuery so please don't make your answer too complicated.

Thank you.

问题是您的ID更改仅能做到这一点:它会更改ID,但是ID的事件处理程序不会自动分配给它

Your event doesnt get attached to the elements that are added dynamically after the page load. Try event delegation. Also, since you are changing the id of the button each time, you can use wildcard selector as shown below Use

$('body').on('click', '[id^=unlike]', function(){ // or [id^=like]
//your logic
});

instead of

$('#unlike_' + <? echo $pid; ?>).click(function() {
});

and similarly change it for like too.

Instead of modifying the element's ID, modify another attribute, such as a class and that way you don't need to re-apply the click event handler and you can use one single event handler to handle ALL the like/unlike buttons instead of looping over them, which looks like what you are doing. And instead of putting a unique number in the ID, you could use the data attribute so that you don't need to worry about extracting the integer from the string (since IDs can't start with integers). In fact, you can completely leave the PHP out of your JavaScript.

So for example, if you have the following HTML:

<div data-id="12345" class="clickme like"></div>
<div data-id="23456" class="clickme unlike"></div>

Where "like" is for a button to like it and "unlike" is for an unlike button. Then you could do the following:

$(document).ready(function() {
    $('.clickme').click(function() {
        // Like it:
        if ($(this).hasClass("like")) {
            var pid = $(this)attr("data-id");
            $.post("test2test.php", {op: "like", pid: pid});
            $(this).removeClass("like");
            $(this).addClass("unlike");
        }
        // Unlike it:
        else {
            var pid = $(this)attr("data-id");
            $.post("test2test.php", {op: "unlike", pid: pid});
            $(this).addClass("like");
            $(this).removeClass("unlike");
        }
    });
});

Also, even though this isn't directly related to your question. It is always a good habit to use prepared statements with parameterized queries mysqli, even if the values come from the database or a source you consider to be trustworthy. For example, your $pid variable goes straight into your query opening you up to SQL injection attacks. Just prepare with parameterized queries and don't worry about what goes into your database.

The button id is changed so the event cannot be triggered. You may use the jQuery ".on()" function instead of ".click()", the event will be trigger even the element is created in the future.

For example,

$('#like_' + pid).on("click",function(){
   alert("The button is clicked");
});

Reference : https://api.jquery.com/on/

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