skip to Main Content

Lets say I have a variable that changes such as-

var c = document.getElementsByClassName('chat incoming').length;

How could I make the latest result of the variable c get compared the the last result of the variable c? Or my question rephrased, how can I make something happen when variable c changes?

No proxy please.

variable c is the amount of that specific element.

Edit:
If you need this code then here it is.

javascript/chat.js

const form = document.querySelector(".typing-area"),
incoming_id = form.querySelector(".incoming_id").value,
inputField = form.querySelector(".input-field"),
sendBtn = form.querySelector("button"),
chatBox = document.querySelector(".chat-box");

form.onsubmit = (e)=>{
    e.preventDefault();
};

inputField.focus();
inputField.onkeyup = ()=>{
    if(inputField.value != ""){
        sendBtn.classList.add("active");
    }else{
        sendBtn.classList.remove("active");
    }
};

sendBtn.onclick = ()=>{
    let xhr = new XMLHttpRequest();
    xhr.open("POST", "php/insert-chat.php", true);
    xhr.onload = ()=>{
  if(xhr.readyState !== undefined && xhr.readyState === 4){ 
      if(xhr.status === 200){
          inputField.value = "";
          var audio = new Audio("php/sounds/good_notification.mp3");
          audio.play();
          scrollToBottom();
      }
  }
};
    let formData = new FormData(form);
    xhr.send(formData);
};
chatBox.onmouseenter = ()=>{
    chatBox.classList.add("active");
};

chatBox.onmouseleave = ()=>{
    chatBox.classList.remove("active");
};

setInterval(() =>{
    let xhr = new XMLHttpRequest();
    xhr.open("POST", "php/get-chat.php", true);
    xhr.onload = ()=>{
      if(xhr.readyState === XMLHttpRequest.DONE){
          if(xhr.status === 200){
            let data = xhr.response;
            chatBox.innerHTML = data;
            if(!chatBox.classList.contains("active")){
                scrollToBottom();
              }
          }
      }
    };
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhr.send("incoming_id="+incoming_id);
}, 500);

function scrollToBottom(){
    chatBox.scrollTop = chatBox.scrollHeight;
  }
function NotifyNewMessage() {
  var c = document.getElementsByClassName('chat incoming').length;
  alert(c);
}

I though about using a database to store this info and have the JavaScript check to see if the latest data in the database is less then c and if it is then do something but I don’t know how.

Edit:
This is the chat.php

<?php 
  session_start();
  include_once "php/config.php";
  if(!isset($_SESSION['unique_id'])){
    header("location: login.php");
  }
?>
<?php include_once "header.php"; ?>
<body>
  <div class="wrapper">
    <section class="chat-area">
      <header>
        <?php 
          $user_id = mysqli_real_escape_string($conn, $_GET['user_id']);
          $sql = mysqli_query($conn, "SELECT * FROM `users` WHERE `unique_id` = {$user_id}");
          if(mysqli_num_rows($sql) > 0){
            $row = mysqli_fetch_assoc($sql);
          }else{
            header("location: users.php");
          }
        ?>
        <a href="users.php" class="back-icon"><i class="fas fa-arrow-left"></i></a>
        <img src="php/images/<?php echo $row['img']; ?>" alt="">
        <div class="details">
          <span><?php echo $row['fname']. " " . $row['lname'] ?></span>
          <p><?php echo $row['status']; ?></p>
        </div>
      </header>
      <div class="chat-box">

      </div>
      <form action="#" class="typing-area">
        <input type="text" class="incoming_id" name="incoming_id" value="<?php echo $user_id; ?>" hidden>
        <input type="text" name="message" class="input-field" placeholder="Type a message here..." autocomplete="off">
        <button><i class="fab fa-telegram-plane"></i></button>
      </form>
    </section>
  </div>

  <script src="javascript/chat.js"></script>

</body>
</html>

4

Answers


  1. You can use a Proxy and than call a function when the object changes. Take a look at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

    Login or Signup to reply.
  2. Currently the way the variable c is set up it would not change automatically even if you add more nodes with class chat-box, because variable c just stores a Number.

    If variable c was just this var c = document.getElementsByClassName('chat-box');, then it would have always been up to date according to the chat-box nodes in the DOM.

    Now, if you want to listen to whenever the length changes, which means more nodes with class chat-box have been added (same goes if you remove nodes). You will have this info wherever you’re updating the chat-box DOM nodes.

    In the following code snippet, I’ve a button that adds a div element with class chat-box into the body, and this change is also reflected by the c variable. So inside the click listener itself I can put other logic as well, which is suppose to run when c changes.

    var c = document.getElementsByClassName('chat-box');
    var d = c.length;
    
    document.querySelector("button").addEventListener("click", (e) => {
      const div = document.createElement("div");
      div.className = "chat-box";
      div.innerText = "Hello World";
      document.body.appendChild(div);
      d = c.length;
    });
    <button>Add Chat Box</button>
    <div class="chat-box">Hello World</div>
    Login or Signup to reply.
  3. c is just a simple number.

    Assuming what is required is to be informed when the number of elements with class chat incoming changes you could first set up a MutationObserver on the relevant container element then when that is called you look to see whether c is still equal to document.getElementsByClassName('chat incoming').length

    MutationObserver is a bit more helpful than just noticing whether a length has changed, as it isn’t just telling you that the number of chat-boxes may have changed, but even if the number is the same you still get to have a look – which you may want because there may have been an addition and a deletion, i.e. the chat has changed.

    Login or Signup to reply.
  4. So in chat.js you should add this at the bottom below everything.

    function NotifyNewMessage() {
      var c = document.getElementsByClassName('chat incoming').length;
      var d = document.getElementById("hidden").value;
      var audio = new Audio("php/sounds/good_notification.mp3");
      if(c != d){
          audio.play();
          document.getElementById("hidden").value = c;
      }
    }
    

    You should also add this

    NotifyNewMessage();
    

    At this

    setInterval(() =>{
        NotifyNewMessage();
        let xhr = new XMLHttpRequest();
        xhr.open("POST", "php/get-chat.php", true);
        xhr.onload = ()=>{
          if(xhr.readyState === XMLHttpRequest.DONE){
              if(xhr.status === 200){
                let data = xhr.response;
                chatBox.innerHTML = data;
                if(!chatBox.classList.contains("active")){
                    scrollToBottom();
                  }
              }
          }
        };
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send("incoming_id="+incoming_id);
    }, 500);
    

    You should put this in chat.php

    <input id="hidden" type="hidden" value="0">
    

    Now the only this you got to do is figure out a way to make the user interact with the document.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search