简体   繁体   中英

The onclick event doesn't work on reloading elements

I have created a user support system to enable users to contact the moderators of my website in case they need help with their account and the opposite.

As of recently, new messages sent to or by the users get loaded only if the page is refreshed , which is not very convenient as a user may sign out without refreshing and therefore not get the message soon.

To counter that, I thought of implementing a setInterval() sending an AJAX request every 1 minute and reloading the messages from the database, so that if new ones exist they will be shown.

While it actually works and reloads the messages, when I click on a message to open it and read it the onclick event is not fired . This happens for all messages without exception.

I thought that the problem was that setInterval() reloaded all the messages every minute instead of checking if new messages exist and reload them only in that case , but despite performing this check in my PHP file the problem still persists.


My PHP code for a notification:

<?php
  $message_status = ($status[$a] === "Read") ? "-open" : ""; ?>
?>

<div class="dashboard-notifs-content">
  <p>
    <i class="fa fa-folder<?php echo $message_status; ?> fa-fw">&nbsp;</i>
    <a class = "user-notifs" notif-id = "<?php echo $ID[$a]; ?>"
       subject = "<?php echo $subject[$a]; ?>" message = "<?php echo $message[$a]; ?>"
       status = "<?php echo $status[$a]; ?>"><?php echo $subject[$a]; ?></a>
  </p>
</div>

My code for the onclick event:

// Show message in preview
$(".user-notifs").on("click", function() {
    // Declare variables and assign to them the content of their respective attributes
    var current = this;
    var id = this.getAttribute("notif-id");
    var subject = this.getAttribute("subject");
    var message = this.getAttribute("message");
    var status = this.getAttribute("status");

    // Assign notification-id to the preview window
    document.getElementById("user-notif-preview").setAttribute("notif-id", id);

    // Display the preview lightbox and show the message
    lightbox.style.display = "block";
    document.getElementById("user-subject").value = subject;
    document.getElementById("user-message").value = message;

    /* Check if the notification has already been opened
    to mark it as read in the database */
    if (status === "Unread") {
        // Mark notification as opened
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (xhttp.readyState === 1) {
                current.previousElementSibling.className = "fa fa-folder-open fa-fw";
            }
        };
        xhttp.open("POST", "notifs.php", true);
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhttp.send("notif_status=Read&notif_id=" + id);
    }
});

My code for setInterval() :

var notifications = document.getElementById("dashboard-notifs");

// Update the notifications
setInterval(function() {
   var yhttp = new XMLHttpRequest();
   var number = $("#dashboard-notifs").children(".dashboard-notifs-content").length;
   yhttp.onreadystatechange = function() {
      if (yhttp.readyState === 4 && yhttp.status === 200) {
         // Display the notifications if the response is not empty
         if (yhttp.responseText.length !== 0) {
            notifications.innerHTML = yhttp.responseText;
         }
      }
   };
   yhttp.open("POST", "update.php", true);
   yhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   yhttp.send("content=notifs&number=" + number);
}, 5000);

I have only managed to find this question on Stack Overflow, which is kind of similar, but unfortunately none of the answers there solves my issue .

You are directly binding the onclick event using on . You should use event delegation .

You can write the onclick event in this way.

$(document).on("click", ".user-notifs",function() {
   //script goes here
});

Instead of document you can also use the parent element closer to the target element.

$(class_or_id_of_closer_parent_ele).on("click", ".user-notifs", function() {
    //script goes here
});

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