You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于JavaScript+AngularJS的JSON比较:页面未保存数据检测需求

Alright, let's work through this. You've already got the two objects for change detection, which is half the battle—here's how to tie it all together for that close-button confirmation flow:

Step 1: Deeply Compare Your Two Data Objects

First, you need a reliable way to check if the user's input (your current data object) differs from the original/saved state. A shallow comparison won't cut it if you have nested fields, so let's use a deep equality check function:

function isDataChanged(original, current) {
  // Check if types match first
  if (typeof original !== typeof current) return true;
  
  // Handle primitive values (strings, numbers, booleans, null, undefined)
  if (typeof original !== 'object' || original === null) {
    return original !== current;
  }
  
  // Get all keys from both objects to ensure we don't miss any fields
  const originalKeys = Object.keys(original);
  const currentKeys = Object.keys(current);
  
  // If key counts differ, data has changed
  if (originalKeys.length !== currentKeys.length) return true;
  
  // Recursively check each key's value
  for (const key of originalKeys) {
    if (isDataChanged(original[key], current[key])) {
      return true;
    }
  }
  
  return false;
}

This function will return true if any field (even nested ones) has been modified.

Step 2: Listen for the Close Action

Next, wire up your "X" close button to trigger the change check. The approach varies a bit depending on whether it's a custom page-level button or the browser's tab close/refresh:

For a Custom Close Button (e.g., modal close, page exit button)

const closeButton = document.querySelector('#your-close-button-id'); // Replace with your button selector

closeButton.addEventListener('click', (event) => {
  // Assume `originalData` is your initial/saved state, `currentData` is the user's input
  if (isDataChanged(originalData, currentData)) {
    const shouldLeave = confirm('Your changes haven\'t been saved. Are you sure you want to exit?');
    if (!shouldLeave) {
      event.preventDefault(); // Stop the close action
      // If this is a modal, you might need to cancel its close logic here too
    }
  }
  // If no changes, let the close action proceed normally
});

For Browser Tab Close/Refresh

If you want to cover cases where the user closes the tab or refreshes the page, use the beforeunload event:

window.addEventListener('beforeunload', (event) => {
  if (isDataChanged(originalData, currentData)) {
    // Modern browsers override custom messages, but we still need these lines to trigger the default prompt
    event.preventDefault();
    event.returnValue = '';
  }
});

Step 3: Keep Your Current Data in Sync with User Input

Make sure currentData always reflects what the user has entered. Listen for input changes on all your form controls to update the object in real-time:

const formControls = document.querySelectorAll('input, select, textarea'); // Target all your input elements

formControls.forEach(control => {
  control.addEventListener('input', () => {
    // Update currentData based on the control type and name attribute
    switch (control.type) {
      case 'text':
      case 'email':
      case 'password':
      case 'textarea':
        currentData[control.name] = control.value;
        break;
      case 'select-one':
        currentData[control.name] = control.selectedOptions[0].value;
        break;
      case 'checkbox':
        currentData[control.name] = control.checked;
        break;
      // Add more cases for other input types (radio, number, etc.) as needed
    }
  });
});

Bonus: Update Original Data After a Successful Save

Once the user clicks "SAVE" and the data is successfully stored, update originalData to match currentData so future close actions don't incorrectly prompt:

function handleSave() {
  // Run your existing validation and save logic first
  validateForm()
    .then(() => fetch('/your-save-endpoint', {
      method: 'POST',
      body: JSON.stringify(currentData),
      headers: { 'Content-Type': 'application/json' }
    }))
    .then(response => response.json())
    .then(() => {
      // Deep copy currentData to avoid reference issues
      originalData = JSON.parse(JSON.stringify(currentData));
      alert('Changes saved successfully!');
    })
    .catch(error => console.error('Save failed:', error));
}

That's it! This setup will detect unsaved changes whenever the user tries to close the page/modal and prompt them to confirm before leaving.

内容的提问来源于stack exchange,提问作者FDavidov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:49:40