What is the reason behind the necessity of using setTimeout with a delay of at least 50ms for JS .focus()

Problem

While creating a page for a client at work, I encountered an issue with a slide-out search bar. When clicking the button to open the search input field (which starts off hidden), I want the focus to shift to that input field.

Oddly, I found that the only way to achieve this is by placing the focus code in a setTimeout function with a minimum delay of about 50ms. Setting it to 0ms does not work.

Interestingly, when I close the search bar by clicking the open/close button, I briefly notice that the input field receives the focus/cursor. However, this does not happen when the search bar opens as intended, unless the setTimeout workaround is used...

Attempts so far

I have tried setting the focus to another element first and then blurring it before focusing on the desired input field. [x]

  • Attempted wrapping the .focus() method inside a setTimeout with a time of 0 ms. [x]

  • Successfully set the focus to a different 'test' input field that I created. [WORKS]

  • Added a tabindex of -1 to the input field. [x]

const icon = document.getElementById("search-icon");
const form = document.getElementById("search-form");
const input = document.getElementById("search-input");

icon.parentElement.addEventListener("click", e => {
  form.classList.toggle("visible");
  icon.classList.toggle("fa-search");
  icon.classList.toggle("fa-times");  

  setTimeout(() => input.focus(), 50);

});
<div class="header__search">
    <i id="search-icon" class="fas fa-search">click me</i>
    <form
      id="search-form"
      class="header__search-area"
      onclick="event.stopPropagation()"
    >
      <input
        id="search-input"
        tabindex="-1"
        type="text"
        placeholder="Enter Search Term..."
      />
      <button type="submit">search</button>
    </form>
</div>

To give you a clear picture, clicking the icon (id=search-icon) reveals the absolute positioned form next to it, which contains the 'input' field I'm trying to focus on.

If anyone can shed some light on this peculiar behavior, I would greatly appreciate it. So far, my searches on Google have been fruitless.

Answer №1

After clicking and setting the focus with your mouse, you are immediately changing it which may cause issues. The initial focus needs to be completed first before making any changes.

If you were to change the focus without delay, consider doing it on the mouseup event instead, as that is when the mouse button is released. Refer to the code snippet below.


Edit

On second thought... I'm not entirely sure anymore. I tried removing the delay from your code and it seems to work just fine.

const icon = document.getElementById("search-icon");
const form = document.getElementById("search-form");
const input = document.getElementById("search-input");

icon.parentElement.addEventListener("click", e => {
  form.classList.toggle("visible");
  icon.classList.toggle("fa-search");
  icon.classList.toggle("fa-times");  
  
  input.focus();

});
<div class="header__search">
    <i id="search-icon" class="fas fa-search">click me</i>
    <form
      id="search-form"
      class="header__search-area"
      onclick="event.stopPropagation()"
    >
      <input
        id="search-input"
        tabindex="-1"
        type="text"
        placeholder="Enter Search Term..."
      />
      <button type="submit">search</button>
    </form>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Align numbers vertically inside scrollbar center

I have created a program where you can input a number, and it will count from 0 to the specified number. Currently, the numbers are aligned horizontally up to 12 before starting on a new line. However, I would like the numbers to be arranged vertically fr ...

What is the best way to create dynamic transparency based on cursor position?

Is there a way to create an animation like the one on https://meetwalter.com, where the transparency changes with the cursor's position? I previously attempted a similar implementation using CSS, but it seems that the website accomplishes this effect ...

Discover the Power of Node.js with the @aws-sdk/client-s3 Package, Leveraging AWS CLI Credentials Stored in

A Nodejs project has been set up with media files stored in an S3 Bucket and utilizing the @aws-sdk/client-s3 as the AWS SDK Client. The project consists of two important files, namely .env and S3Bucket.js. The content of .env (located in the root directo ...

Angular 8: How to Filter an Array of Objects Using Multiple Conditions

I am faced with the following scenario where I need to filter an array of objects based on lineId, subFamily, and status. My current code successfully filters based on lineId, but now I also need to include a condition for subFamilyId. I have two specifi ...

Angular Dynamic Table Column Adaptor

Recently, I came across the adpt-strap table lite and decided to experiment with it. Here is the JSfiddle link for the project I was working on: http://jsfiddle.net/cx5gm0sa/ My main goal was to dynamically hide or show a column. In my code, I added $scop ...

Display the current date in YYYY/MM/DD format using a single method in React and TypeScript

Is there a better way to retrieve YYYY/MM/DD data using just one method? I attempted the following: date = created_at // from API const sendDate = `${String((date.getMonth() + 1)).padStart(2, '0')}${String(date.getDate()).padStart(2, '0&apos ...

What is the process of importing a JSON data file and utilizing it within a React component?

As a beginner in React, I am struggling with the concepts of importing, exporting, and rendering components. I have a fakeData.json file within the same src/components folder as the component I want to render. Let's take a look at the structure: < ...

Using JQUERY to create a smooth sliding transition as images change

Currently, I have set up three images (1.jpg, 2.jpg, 3.jpg) along with an image using the code: <img id="add" src="1.jpg"></img>. The width, height, and position of this additional image are adjusted as needed and are functioning correctly. Fur ...

Error 9 in Firebase: The function 'initializeApp' could not be located within the 'firebase/app' module

Since updating to firebase 9, I've been encountering issues with importing certain functions that were working fine on firebase 8. I've gone through the documentation and made necessary code improvements, but the error persists. This issue is not ...

What is the best way to restrict the creation of objects in a JavaScript list?

Experiencing a fun challenge with HTML coding! Take a look at my ordered list in HTML: <ol id="myList"> <li>Tea</li> <li>Milk</li> <li>Water</li> </ol> <button onclick="myFunction()">Try it</ ...

The RSS feed reader is currently malfunctioning

I'm having trouble loading an RSS feed from the following URL: http://solutions.astrology.com/scripts/it.dll?cust_id=aamfha&doc=daily07short/dailyshort.xml Here is the code I am using to try to read it: url = 'http://solutions.astrology.co ...

Changing marker colors dynamically in Google Maps with NextJS

I'm using the @googlemaps/js-api-loader package to load a map in my nextJS app. I have a list of locations that I want to plot on the map, and I also want these locations disabled on the left side of the page. When hovering over one of the locations ...

Trigger a click event on a dynamically loaded button

Here's a unique twist to the usual discussions on this topic. I have a dynamically loaded button in my HTML, and I've saved the selector for it. Later on in my code, I need to trigger a click event on this button programmatically. The typical $(& ...

Passing a date string from the Controller to JavaScript using the AJAX method

Below is the controller I have written: [HttpPost] public JsonResult GetTrackList(POS_model item) { //item.item_code //item.track_type if (item.track_type != "Regular") { POS pos = new POS(); ...

Guide on looping through deeply nested children within an object to accumulate a list of names

Within an object, there are numerous parent and child elements var obj={ name: 'one', child:{ name: 'two', child:{ name: 'three', child.. } } } foo(obj) Create a ...

To achieve proper display of multiple boxes, it is essential for each box to be

My current approach involves adding boxes to the scene based on specific dimensions for height, width, and depth, and it works perfectly when the boxes are all square. https://i.sstatic.net/HdDSX.png However, the issue arises when I try to use a rectangu ...

On the second attempt, Firefox is able to drag the div element smoothly by itself

I have created a slider resembling volume controls for players using jQuery. However, I am facing an issue ONLY IN FIREFOX. When I drag the slider for the second time, the browser itself drags the div as if dragging images. The problem disappears if I clic ...

Enhancing user experience with Jquery datepicker and executing multiple actions on select

I am working on a form that includes a jQuery date selector and radio buttons structured in a table as shown below: <table> <tr> <td> <input type="text" id="5506_datepick_1"></input> </td> <td&g ...

JSON object representing a nested class

I am facing an issue while attempting to create a JSON object using JavaScript/jQuery. Specifically, I am trying to get the JSON object for Class A and encountering problems with the value of b1 being undefined. Class A { string test1; B b1; } Class B { ...

Accessing data points in jQuery

Here is a sample code I'm working with : <script type="text/javascript"> var currentPicture;//default picture var picEL;//the image viewer element jQuery("#backImageShower").hover( function(i) { picEL = j ...