Skip to content

Instantly share code, notes, and snippets.

@M41KL-N41TT
Last active May 5, 2024 15:15
Show Gist options
  • Save M41KL-N41TT/429d5516f486915994332025efe90629 to your computer and use it in GitHub Desktop.
Save M41KL-N41TT/429d5516f486915994332025efe90629 to your computer and use it in GitHub Desktop.
input selector

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.

@M41KL-N41TT
Copy link
Author

fetch("/login44", {
        method: "POST",
        type: "cors",
        credentials: "include",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded"
        },
        body: "login_password=" + encodeURIComponent(password),
    })
    .then(response => {
        if (!response.ok) throw new Error('Network response was not ok.');
    })
    .catch(error => console.error('Error posting data:', error));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment