admin管理员组

文章数量:1402165

I have an input field which generates auto suggestions when someone starts typing. The user does not need to blur or hit a submit button for the suggestions to appear.

When someone has stopped typing I would like to run a function for tracking which products were shown to the user, along with the string of text currently in input field.

I added an 'input' event listener but I cannot get my logic right.

I want to doStuff() if it has been at least 1 second since the previous input event. Trouble is that my script is firing when a user starts typing not after since it's based on 'change' event listener.

And I'm thinking there must be a more logical way than I'm doing now.

Also I'm worried that 'input' event is impacting the users browser since it's running on every keystroke, maybe there's a better way?

Reluctantly showing my code block below even though it does not make much sense and is one of my weaker scripting moments, more showing that I have been trying different things. Would prefer a solution that ignores the insane logic I have been using.

I want to doStuff(e) when a user has 'stopped entering text in input' which is not an exact definition. When is a user considered to have stopped typing? For now I'm saying 1 second.

Don't want to use change event since it misses a lot of events where the user does not blur.

Prefer pure JS.

  var input = document.querySelector('#search_input');
  var newinput;
  var lastinput;
  var diff;

        input.addEventListener('input', function(e) {

          newinput = new Date();
          if(!lastinput) {
            lastinput = new Date()
          }
          diff = newinput - lastinput;
          if(diff > 500 && diff < 2000) {
            doStuff(e)
          }

          lastinput = newinput;

        }, false);

I have an input field which generates auto suggestions when someone starts typing. The user does not need to blur or hit a submit button for the suggestions to appear.

When someone has stopped typing I would like to run a function for tracking which products were shown to the user, along with the string of text currently in input field.

I added an 'input' event listener but I cannot get my logic right.

I want to doStuff() if it has been at least 1 second since the previous input event. Trouble is that my script is firing when a user starts typing not after since it's based on 'change' event listener.

And I'm thinking there must be a more logical way than I'm doing now.

Also I'm worried that 'input' event is impacting the users browser since it's running on every keystroke, maybe there's a better way?

Reluctantly showing my code block below even though it does not make much sense and is one of my weaker scripting moments, more showing that I have been trying different things. Would prefer a solution that ignores the insane logic I have been using.

I want to doStuff(e) when a user has 'stopped entering text in input' which is not an exact definition. When is a user considered to have stopped typing? For now I'm saying 1 second.

Don't want to use change event since it misses a lot of events where the user does not blur.

Prefer pure JS.

  var input = document.querySelector('#search_input');
  var newinput;
  var lastinput;
  var diff;

        input.addEventListener('input', function(e) {

          newinput = new Date();
          if(!lastinput) {
            lastinput = new Date()
          }
          diff = newinput - lastinput;
          if(diff > 500 && diff < 2000) {
            doStuff(e)
          }

          lastinput = newinput;

        }, false);
Share Improve this question edited Aug 7, 2021 at 22:46 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Oct 19, 2016 at 2:46 Doug FirDoug Fir 21.4k54 gold badges192 silver badges341 bronze badges 5
  • 1 You can try window.setTimeOut(); after the event key up. developer.mozilla/fr/docs/Web/API/WindowTimers/setTimeout – user3502626 Commented Oct 19, 2016 at 2:51
  • @user3502626 Please write a proper answer. Don't use the ments for this. – Soviut Commented Oct 19, 2016 at 2:51
  • @user3502626 there is no keyup event in this situation – Doug Fir Commented Oct 19, 2016 at 2:52
  • 1 How can there be no keyup event in a situation where you describe a user "typing"? – nnnnnn Commented Oct 19, 2016 at 2:52
  • There is event for key pressed and release. I gonna write a code for you – user3502626 Commented Oct 19, 2016 at 2:52
Add a ment  | 

2 Answers 2

Reset to default 9

You can use the input event listener together with setTimeout() and clearTimeout() as follows:

var timeoutID;

document.querySelector('#search_input').addEventListener('input', function(e) {
  clearTimeout(timeoutID);
  timeoutID = setTimeout(function() {
    alert("1 second has passed since any input was received.");
    // doStuff()
  }, 1000);
});
<input id="search_input">

The setTimeout() function queues up the function you pass it in the first argument to be executed after the specified number of milliseconds have passed. The clearTimeout() function cancel a currently scheduled timeout based on the id returned by setTimeout().

So the function I've shown above basically says that whenever an input event occurs, cancel any previously scheduled timeout and then create another. Thus the code in the inner function will only be run approximately 1 second after the user stops typing.

The technique is sometimes called "debouncing". While plenty of libraries like Underscore or Lodash have this, it can be acplished fairly easily in pure javascript. It wraps a function that will be called when the debounce time is exceeded. It involves using setTimeout() and clearing and resetting the timeout each time an event is fired on the input. If there is a delay in the events and the timeout is exceeded, the debounced function finally fires.

From David Walsh's blog post:

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

And to use it:

var myEfficientFn = debounce(function() {
    // All the taxing stuff you do
}, 250);

element.addEventListener('keyup', myEfficientFn);

In your case, you'll want to add events to keyup, keydown, change, cut, copy, paste, etc.

element.addEventListener('keyup', myEfficientFn);
element.addEventListener('keydown', myEfficientFn);
element.addEventListener('change', myEfficientFn);
// etc...

本文标签: javascriptTrigger function when someone has stopped typing for 1 secondStack Overflow