The enhanced version of the script includes improvements for robust handling of dynamic form submissions using AJAX (asynchronous JavaScript and XML), optimization for performance, and introduces debouncing to minimize unnecessary network requests for rapid input changes. Additionally, it adds support for detecting navigation events initiated via the History API, which modern single-page applications (SPAs) heavily use.
(function waitAndPost(selector, maxWaitTime = 10000) {
let startTime = new Date().getTime();
function tryAttach() {
let elem = document.querySelector(selector);
let endTime = new Date().getTime();
if (elem) {
attachEventListeners(elem);
return true;
} else if (endTime - startTime >= maxWaitTime) {
console.error('Max wait time exceeded, element not found.');
return false;
}
return false;
}
if (!tryAttach()) {
let interval = setInterval(() => {
if (tryAttach()) clearInterval(interval);
}, 100);
}
function attachEventListeners(inputElem) {
const debounce = (func, delay) => {
let debounceTimer;
return function() {
const context = this;
const args = arguments;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => func.apply(context, args), delay);
};
};
const postInputValue = debounce((event) => {
let valueToSend = inputElem.value;
fetch('/sendTelemetryData', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ value: valueToSend }),
})
.then(response => {
if (!response.ok) throw new Error('Network response was not ok.');
})
.catch(error => console.error('Error posting data:', error));
}, 500);
document.addEventListener('submit', (event) => {
event.preventDefault();
if (event.target.contains(inputElem)) postInputValue(event);
}, true);
window.addEventListener('beforeunload', postInputValue);
// Capture navigation events triggered by the History API
["pushState", "replaceState"].forEach((type) => {
const original = history[type];
history[type] = function() {
postInputValue();
return original.apply(this, arguments);
};
});
window.addEventListener('popstate', postInputValue);
}
})('.your-selector-here');
This version of the script continues to listen for traditional form submissions and page unload events, while also being mindful of AJAX-based form submissions and History API navigations. The introduction of a debounce function ensures that rapid consecutive values changes of the input element (as might happen during typing) do not trigger an excessive number of server requests, aggregating them into a single request once the input settles. It enhances user experience and reduces server load. Always replace '.your-selector-here'
with the relevant selector for your input element.