如何让 JavaScript 检测变量 c 何时发生变化并执行某些操作?

问题描述

假设我有一个变量,例如-

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

如何将变量 c 的最新结果与变量 c 的最后结果进行比较?或者我的问题改写了,当变量 c 发生变化时,我怎么办?

请不要代理。

变量 c 是该特定元素的数量

编辑: 如果您需要此代码,那么就在这里

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);
}

我想使用数据库来存储这些信息,并让 JavaScript 检查数据库中的最新数据是否小于 c,如果是,则执行某些操作,但我不知道如何操作。

编辑: 这是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>

解决方法

c 只是一个简单的数字。

假设需要在类聊天传入的元素数量发生变化时得到通知,您可以首先在相关容器元素上设置 MutationObserver,然后在调用时查看 c 是否仍然等于 {{ 1}}

MutationObserver 比仅仅注意长度是否改变更有帮助,因为它不仅告诉您聊天框的数量可能已经改变,而且即使数量相同,您仍然可以拥有看看 - 您可能需要,因为可能有添加和删除,即聊天已更改。

,

目前变量 c 的设置方式即使添加更多类为 chat-box 的节点也不会自动改变,因为变量 c 只存储一个 Number .

如果变量 c 就是这个 var c = document.getElementsByClassName('chat-box');,那么根据 DOM 中的 chat-box 节点,它会一直是最新的。

现在,如果您想在长度变化时收听,这意味着添加了更多类 chat-box 的节点(如果删除节点也是如此)。无论您在哪里更新 chat-box DOM 节点,您都会获得此信息。

在下面的代码片段中,我有一个按钮,它将一个 div 类的 chat-box 元素添加到主体中,并且此更改也反映在 c 变量中。因此,在点击侦听器本身内部,我也可以放置其他逻辑,假设在 c 更改时运行。

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>

,

因此,在 chat.js 中,您应该将其添加到所有内容下方的底部。

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;
  }
}

你也应该添加这个

NotifyNewMessage();

此时

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);

你应该把它放在chat.php中

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

现在你唯一要做的就是想办法让用户与文档交互。

,

您可以使用代理,而不是在对象更改时调用函数。看看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy