-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
hasfocus won't set focus if element is hidden #355
Comments
Good point - I'll update the |
in IE6 setting focus to invisible element actually causes error. Would it be possible to skip an attempt to set focus to an invisible element? |
My customized version of update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
setTimeout(function() {
if (value
&& element.offsetWidth && element.offsetHeight
&& document.activeElement && document.activeElement != element)
{
element.focus();
ko.utils.triggerEvent(element, "focusin"); // For IE, which doesn't reliably fire "focus" or "blur" events synchronously
}
});
} It also will only set the focus and not clear it, and it checks if the element is already in focus first. |
mbest, |
Here's the example using my revised update function: http://jsfiddle.net/mbest/tAGmp/ Try it out. |
Your example works fine - no question about that. I'll try to shorten mine into a fiddle soon-ish |
nayato - are you saying there is some other situation we should handle? I guess we do want to avoid throwing actual errors while trying to focus elements. Perhaps we could look at what jQuery does to handle this situation (maybe just try-catch?). |
jQuery docs say: mbest, I've found the culprit in my case: adding " && !element.disabled" to condition in your version of hasfocus does the trick. Here's my markup (it's text field with watermark): <div class="wrap">
<div class="watermark" data-bind="click: focusAddress, visible: !(addressFocused() || address()), text: watermark"> </div>
<input data-bind="value: address, valueUpdate: 'afterkeydown', hasfocus: addressFocused, disable: $root.busy" />
</div> |
IE gives an error even if you use try/catch. |
It didn't throw in my case with this: try {
value ? element.focus() : element.blur();
ko.utils.triggerEvent(element, value ? "focusin" : "focusout");
} catch (ex) { } |
Okay. I'll check it out again. |
So |
mbest, I'd prefer your approach with no try-catch as it a) works just as well with IE b) does a bit more c) I just feel uncomfortable having try-catch for no good reason |
Hmm, if jQuery is unable to avoid throwing errors in the case of attempting to focus a hidden element, perhaps that suggests it's more trouble than it's worth. I'd be especially keen to avoid any use of I would give this a low priority unless an extremely neat solution occurs to anyone. |
There's a big difference between jQuery and Knockout. jQuery is generally used imperatively, whereas Knockout is mostly declaratively. Also, I think Knockout is at a higher level (less low level) than jQuery in terms of DOM manipulation. When doing DOM stuff with jQuery, you could just have your code check if the element is visible first. With Knockout, the binding should do all the DOM stuff for you, and all you should have to think about is your bindings and model. |
I was taking a look at the jQuery code (ver 1.7) and found the following in
|
A simple fix could be to make it configurable, if the binding also should blur the element on update - maybe the intersection use case is close to zero...? (might be a bit out of context here - but i also read #352 before...) |
By just doing the focus() in a setTimeout whenever the element is hidden, fixes the problem (I'm not sure if this could have race condition problems, though..) Have a look here: |
Just upgraded my fork and found out, that this is still current. #671 works ok for me - but it uses a setTimeout... |
Demonstration: http://jsfiddle.net/mbest/NTKcU/
Input 1 is in a template that is hidden while it's parsed (visible after if).
Input 2 is in a template that is visible while it's parsed (visible before if).
The button switches between them. The input will be focused for input 2 but not for input 1.
Scenario for input 1 is useful to avoid flashing, especially in Firefox, when the template includes control-flow.
The text was updated successfully, but these errors were encountered: