基于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

