I am trying to see if the following is possible:
$(document)
, $(body)
, $(window)
and the like due to performance reasons.My implementation consists of a very simple HTML navigation bar as seen in the snippet below. I do native keyboard navigation between each <a>
tag. The first list element is the title, containing an anchor that is visible, the second element
<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 goal of this navigation bar is simple:
I have 1 and 2 down, but 3 is tricky because of the requirements listed above. I know this can be very easily be done using a global selector, but this challenge is about figuring out and understanding if it can be done otherwise.
$(document).ready(function() {
dropdownMenu = $(".test > ul");
dropdownMenu.hide();
$(".test").focusin(function() {
if (dropdownMenu.is(":hidden")) {
dropdownMenu.show();
}
});
// Some selector for some event here to handle the focus/clicks outside the $(".test") element
});
Important: I consider event.stopPropagation();
, as explained in CSS Tricks - The Dangers of Stopping Event Propagation to be a dangerous technique for the scope of this question, however if using said technique results in the most efficient approach then I will welcome it.
You can listen for a click event on document and then make sure #menucontainer is not an ancestor or the target of the clicked element by using . closest() . If it is not, then the clicked element is outside of the #menucontainer and you can safely hide it.
Answer: Use the event. target Property You can use the event. target property to detect a click outside of an element such as dropdown menu.
To check whether a specific element has focus, it's simpler: var input_focused = document. activeElement === input && document. hasFocus();
I'm not sure I'm following the question 100% but I think I got you.
You can use event.target
with closest
using the focusin
event.
$(document).on('focusin', function (event) {
var $target = $(event.target);
if (!$target.closest('.bar').length) {
console.log('You focused outside of .bar!');
}
});
Here's a fiddle: https://jsfiddle.net/crswll/qk14r7c7/2/
One option here, without global selectors, is to delay the close action briefly:
var isVisible = false;
$(".test").focusin(function() {
if (dropdownMenu.is(":hidden")) {
dropdownMenu.show();
}
isFocused = true;
});
$(".test").focusout(function() {
isFocused = false;
setTimeout(function() {
if (!isFocused && dropdownMenu.is(":visible")) {
dropdownMenu.hide();
}
}, 100);
});
This is a little fiddly, but protects you from errant closes while tabbing. See https://jsfiddle.net/d5fa5o8q/4/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With