在点击加载更多按钮期间,一些div变得不可点击

I have undercome a problem when implementing a "Show more button"

The page will initially display 5 rows of data, then on click the button will make a call to a php function through ajax and load more results, ultimately displaying them on the page. It does this very well.

The problem is that each of the divs are clickable in their own right to allow for user interaction. Before clicking the button the first 5 are clickable and work correctly, however after loading the first 10, the first 5 become unclickable and the rest work as expected.

See my code here:

HTML:

<div class="col-sm-12 col-xs-12 text-center pushDown">
    <div id="initDisplay">
        <?php
            // Display all subjects
            echo displaySubjects($limit);
        ?>
    </div>

    <div id="show_result"></div>
    <button id="show_more" class="text-center pushDown btn btn-success">Show More</button>
</div>

On click of the button the following is happening: JQuery:

<script>
    $("#show_more").on("click", function() {
        $("#initDisplay").fadeOut();
    });

    /* This bit is irrelevant for this question
    $("#addBtn").on("click", function(){
        addSubject();
    });
    */

    var stag = 5;

    $("#show_more").on("click", function(){
        stag+=5;

        console.log(stag);

        $.ajax({
            dataType: "HTML",
            type: "GET",
            url: "../ajax/admin/loadSubjects.php?show="+stag,
            success: function(result){
                $("#show_result").html(result);
                $("#show_result").slideDown();
            }
        });

        var totalUsers = "<?php echo $total; ?>";

        if(stag > totalUsers) {
            $("#show_more").fadeOut();
        }
    });
</script>

My PHP page and functions are here:

<?php

include_once '../../functions/linkAll.inc.php';

$limit = filter_input(INPUT_GET, "show");

if (isset($limit)) {
    echo displayUsers($limit);
} else {
    header("Location: ../../dashboard");
}

function displaySubjects($limit) {
    $connect = db();
    $stmt = $connect->prepare("SELECT * FROM Courses LIMIT $limit");

    $result = "";

    if ($stmt->execute()) {
        $results = $stmt->get_result();

        while($row = $results->fetch_assoc()){
            $id = $row['ID'];
            $name = $row['Name'];
            $image = $row['image'];

            if($image === ""){
                $image = "subjectPlaceholder.png"; // fail safe for older accounts with no images
            }

            $result .=
            "
                <div class='img-container' id='editSubject-$id'>               
                    <img class='miniProfileImage' src='../images/subjects/$image'>
                    <div class='middle' id='editSubject-$id'><p class='middleText'>$name</p></div>
                </div>
            ";

            $result .= "<script>editSubjectRequest($id)</script>";

        }
    }

    $stmt->close();
    return $result;
} 

The script being called through this is:

function editSubjectRequest(id) {
    $("#editSubject-"+id).click(function(e) {
        e.preventDefault(); // Prevent HREF

        console.log("You clicked on " + id);

        $("#spinner").show(); // Show spinner
        $(".dashContent").html(""); // Empty content container

        setTimeout(function() {
            $.ajax({ // Perform Ajax function
                url: "../ajax/admin/editSubjects.php?subjectID="+id,
                dataType: "HTML",
                type: "POST",
                success: function (result) {
                    $("#spinner").hide();
                    $(".dashContent").html(result);
                }
            });
        }, 1500); // Delay this for 1.5secs
    }); 
}

This will then take the user to a specific page depending on the subject which they clicked on.

Your problem is duplicate ids. First five items are present on the page always. But when you load more, you are loading not new items, but all, including first five. As they are already present on the page, their duplicates are not clickable. The original items are however clickable, but they are hidden.

Here is what you need:

$("#show_more").on("click", function(){
  $("#initDisplay").html("");
});

Don't just fadeOut make sure to actually delete that content.

This is the easiest way to solve your issue with minimum changes. But better option would be to rewrite your php, so it would load only new items (using WHERE id > $idOfLastItem condition).

Also you don't need that script to be attached to every div. Use common handler for all divs at once.

$("body").on("click", "div.img-container", function() {
  var id = $(this).attr("id").split("-")[1];
});

When you are updating a DOM dynamically you need to bind the click event on dynamically added elements. To achieve this change your script from

 $("#editSubject-"+id).click(function(e) {

To

 $(document).on("click","#editSubject-"+id,function(e) {

This will bind click event on each and every div including dynamically added div.