I have small widget that has a list of links, which can open and close:
<div class="widget">
<input class="focuser">
<a href="javascript:;">View options</a>
<ul>
<li>Option 1</li>
<li>Option 1</li>
</ul>
</div>
So, when I click on View options
- list appears, and when click on any option - do stuff and close list of options.
And I need to have click-outside-close
functionality - when user clicks anywhere outside just close the list.
I achieved this by focusing an invisible input when showing the options, and on blur
of the input - hide the options after some timeout. This way:
- when user clicks outside - the blur timeout runs out - hide the options.
- if user clicks any option - clear the timeout, hide options & do stuff.
And the problem now is that sometimes the timeout ends before the click. I increased the timeout interval to 200ms, but it's still not 100% sure, and also - this way user sees delay before the options list close.
Any idea how to fix and/or improve this?
EDIT:
This is simplified version of the JavaScript code:
CartSidebar.DwCustomSelect = Ember.View.extend({
blurTimeout: false,
focusOut: function(e) {
if (e.target.className == 'focuser') {
var self = this;
this.blurTimeout = setTimeout(function() {
clearTimeout(self.blurTimeout);
$(self.element).removeClass('opened'); // hide options ..
}, 180);
}
},
click: function(e) {
var clickedElement = e.target;
clearTimeout(this.blurTimeout);
if (clickedElement.tagName.toLowerCase() == 'li') {
$(this.element).removeClass('opened'); // hide options ..
doStuff();
}
}
}
EDIT 2:
I created a plunker, so you can see it in action:
https://plnkr.co/edit/boA6yC0sEbLAZU9tjyso?p=preview
(I did the timeout too small, so you see the problem. But even if you increase the interval - you'll see that the focusOut
triggers before the click
.)