user3383675
user3383675

Reputation: 1081

JS process input after delay only once

I want to listen input field and run processing input value to output value after 3 seconds after finnishing of inputting value.

<html>
<head>
<meta charset="utf-8">
<script src="jquery.js"></script>
<script>
$(document).ready(function() {
    $('.input').on('input', function() {
        var value = $(this).val();
        console.log('Triggered input: ' + value);

        setTimeout(function() {
            console.log('Changing output to: ' + value);
            $('.output').text(value); // example operation
        }, 3000);
    });
});
</script>
</head>
<body>

<input type="text" class="input" />
<hr>
<div class="output">...</div>

</body>
</html>

But the code above will process every single character, instead of expected full string.

In the other words. I want to type "abc", and this value should be processed only one time after delay as "abc", instead of, as now as, as "a", then "ab", then "abc".

How to fix that?

Upvotes: 1

Views: 587

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1075059

But the code above will process every single character, instead of expected full string.

That's because you're using the value variable, whose value you set when scheduling the function. If you want the value as of when the function runs, wait and get it then:

$('.input').on('input', function() {
    var input = $(this);

    setTimeout(function() {
        var value = input.val();
        console.log('Changing output to: ' + value);
        $('.output').text(value); // example operation
    }, 3000);
});

Now the function will use the value of the input as of when the function runs. But there's another problem: If you get multiple events within the three seconds, you'll get multiple calls. You probably want to cancel earlier calls to that function if you get another input event before the function fires? E.g.:

$('.input').on('input', function() {
    var input = $(this);

    // Cancel any outstanding call (no-op if it's already happened)
    var handle = input.data("handle");
    if (handle) {
        clearTimeout(handle);
    }

    // Schedule the new one
    handle = setTimeout(function() {
        var value = input.val();
        console.log('Changing output to: ' + value);
        $('.output').text(value); // example operation
        // Since we've fired, clear the handle
        input.data("handle", 0);
    }, 3000);

    // Remember that handle on the element
    input.data("handle", handle");
});

Upvotes: 3

Related Questions