Identifying the moment when attention shifts away from an element

Is it possible to detect when focus occurs outside an element without relying on global selectors like $(document), $(body), or $(window) for performance reasons?

  • If achieving this without global selectors is not feasible, provide a provable reason explaining why. It's crucial for me to understand the limitations of today's techniques.
  • Bonus Round: Identify the most efficient selector(s)/event handler(s)/plugin(s) for this task in terms of computation time.

View my implementation featuring a simple HTML navigation bar with native keyboard navigation between anchor tags. The goal is to display a dropdown menu when focusing on inner anchor elements and hide it when not focused.

<ul class="test">
  <li>
    <a href="#">Title</a>
  </li>
  <li>
    <ul>
      <li>
        <a href="#">Some link</a>
      </li>
      <li>
        <a href="#">Some link</a>
      </li>
      <li>
        <a href="#">Some link</a>
      </li>
      <li>
        <a href="#">Some link</a>
      </li>
    </ul>
  </li>
</ul>

The objectives are:

  1. Navigate between anchors using keyboard tab or shift+tab.
  2. Show the drop-down menu when focusing on inner anchors.
  3. Hide the drop-down menu when the focus is outside any inner anchors.

I have achieved 1 and 2, but 3 presents a challenge due to the limitations mentioned earlier. While using a global selector would make this task easy, I am exploring alternative solutions.

$(document).ready(function() {
    dropdownMenu = $(".test > ul");
    dropdownMenu.hide();

    $(".test").focusin(function() {
        if (dropdownMenu.is(":hidden")) {
          dropdownMenu.show();
        }
    });
    // Need a selector/event to handle focus/clicks outside $(".test") element
});

Note: I am cautious about using event.stopPropagation(); as described in CSS Tricks - The Dangers of Stopping Event Propagation. However, I am willing to consider it if it proves to be the most efficient approach.

Answer №1

It seems like I might not have fully grasped the question, but I believe I understand what you're asking.

To achieve this, you can utilize the event.target in conjunction with the closest method within the context of the focusin event.

$(document).on('focusin', function (event) {
  var $target = $(event.target);
  if (!$target.closest('.bar').length) {
    console.log('You have focused outside of the .bar element!');
  }
});

You can also find a working example on JSFiddle: https://jsfiddle.net/crswll/qk14r7c7/2/

Answer №2

If you want a solution without using global selectors, consider adding a delay to the closing action:

  var isVisible = false;

  $(".selector").focusin(function() {
    if (menu.is(":hidden")) {
      menu.show();
    }
    isVisible = true;
  });

  $(".selector").focusout(function() {
    isVisible = false;
    setTimeout(function() {
      if (!isVisible && menu.is(":visible")) {
        menu.hide();
      }
    }, 100);
  });

This may seem complicated, but it helps prevent accidental closures while navigating through tabs. Check out https://jsfiddle.net/abc123/3/

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

Attempting to create a dynamic dropdown menu with animated effects triggered by a key press

I've been attempting to construct a menu that initially appears as a small icon in the corner. Upon pressing a key (currently set to click), the checkbox is activated, initiating the animation. Most of the menu and animation are functional at this po ...

Ways to dynamically apply styles to the component tag depending on the visibility of its content

Consider a scenario where you have a component with logic to toggle the visibility of its contents: @Component({ selector: 'hello', template: `<div *ngIf="visible"> <h1>Hello {{name}}!</h1></div>`, styles: [`h1 { fo ...

I am unable to utilize folder paths in CSS within my React application

Having trouble setting a background image in CSS within my React app. When styling and setting the image from a React component, it works just fine. Can anyone provide assistance? This code snippet will work: const style={ width:'300px', ...

"Discover the magic of creating a navigation menu with jQuery toggle - let me show

Recently, I managed to create a side navigation using the target function in CSS3. However, I am curious about how I can achieve the same result using jQuery without disrupting the layout. Any assistance would be greatly appreciated. Here is the code sni ...

What are the steps to transforming shorthand CSS into longhand?

Is there a tool available that can automatically convert shorthand CSS to longhand? I am in need of this functionality because I would like to utilize SmartSprites, which is not compatible with shorthand formatting. Additionally, if there is a tool that c ...

Transform your ordinary HTML select into a stylish span with this custom CSS class

I need help making a select element appear like a span under certain conditions. The CSS class I currently have works with input boxes, but not with dropdowns. Is there any advice on how to style the select element to look like a span without actually repl ...

downloading responsive design

Using media queries to define backgrounds with separate images based on browser size: @media (min-width:1440px){div.container{background:URL('bg1440.png');}} @media (min-width:960px){div.container{background:URL('bg960.png');}} @media ...

Switching to a dropdown navigation option

Sorry for the repetition, but I haven't been able to find a solution to my problem yet, so here I am asking again. I am still getting the hang of html5 and css3, and while I've managed so far, I'm stuck now. I want to turn one of the option ...

jQuery Mobile is experiencing page height inaccuracies

My web application, built with jQuery Mobile 1.2.0, is encountering an issue with page height calculations on Windows Phone. While iOS and Android display correctly, there is a gap at the bottom of the page on Windows Phone. Is there a CSS-only solution t ...

How can I clear all jQuery toggled classes that have been added across the entire webpage in an Angular project?

Upon clicking a link within an element, the following CSS is applied: <a class="vehicleinfo avai-vehicle-info-anc-tag" ng-click="vehicleInfo($event)">Vehicle Info <span class="s-icon red-down-arrow"> </span> </a> $scope.vehic ...

The unique design of the list extends beyond the boundary line

In my current project, I am utilizing next.js and MUI (material-ui). The component I am working with has the following structure: <Paper> <List> .. </List> </Paper> One issue I am facing is that when the list is scrolled, the ...

How can I make a CSS transition activate only on width increases, not decreases?

My element's width changes under different conditions, and I've implemented CSS with a transition for the width: .element-class { transition: width 500ms ease 0ms; } However, I only want the transition to occur when the width is decreasing. ...

Conceal excessive content on elements set in a stationary position

How can we prevent overflow of a fixed div within a container? Initially, I attempted nesting fixed elements inside each other, but that did not solve the issue. The only solution that comes to mind is using "inverted" masks: other fixed divs that hide eve ...

The background color feature of a div is malfunctioning

I have encountered a strange issue with one of my Div elements. When I add text inside the div, the background color sticks to the text. However, if there is no text present, the background color disappears. Image with Text: https://i.stack.imgur.com/oYK ...

`Cannot Get jQuery ScrollTop Function to Work for 2nd Element`

Having trouble with an issue. Let me explain. I implemented a scrollTop Jquery on page load that scrolls down after a delay to prompt user action. However, I'm facing a problem where another scrollTop doesn't work after clicking buttons "#b3,#b3 ...

Changing the color of a specific span using Angular

I am working with a dynamic mat-table where columns are added and populated on the fly. The table headers are styled using divs and spans. My goal is to change the color of a header to black when clicked, but also un-toggle any previously selected header. ...

What steps should I take to make my Vue JS delete function operational?

As I work on developing my website, I've encountered some challenges. Being new to coding, I'm struggling with creating a functional delete user button. When I click delete, it redirects me to the delete URL but doesn't remove the entry from ...

Tips for updating the color of the first td element in a table using a specific class

Below is the CSS code for my table: table.show-my-request-table { border: 1px solid black; margin-left:auto; margin-right:auto; border-collapse: collapse; } tr.show-my-request-table-header{ border: 1px solid black; } tr.show-my-requ ...

Arranging two stretchable div elements side by side

I'm currently working on a web page layout where I want two divs to be flexible and adjust their size as the browser window is resized. However, I've encountered an issue where instead of shrinking, the line breaks between the two divs when the w ...

Optimizing Window Width with React.js and CSS

I'm currently in the process of building a responsive website with react. I am utilizing CSS stylesheets for styling and have used @media queries to ensure responsiveness. However, I've encountered an issue while testing in Chrome where the elem ...